JAVA之Set、Map集合

本文深入解析Set、Map集合的特点与应用,包括HashSet、TreeSet、HashMap、TreeMap的内部机制,以及Collections工具类的常用方法,是理解Java集合框架的关键资源。

1.Set集合

1.1set集合概述及特点

1.1.1概述

Set集合为集类型,集是最简单的一种集合,存放于集中的对象不按特定方式排序,只是简单地把对象加入集合中,类似于向口袋里放东西。对集中存在的对象的访问和操作是通过对象的引用进行的,因此在集中不能存放重复对象。Set集合包括Set接口以及Set接口的所有实现类。因为Set接口继承了Collection接口,所以Set接口拥有Collection接口提供的所有常用方法。

1.1.2特点

a.一次只能存一个元素。

b.不能储存重复的元素。

c.存储顺序和取出来的顺序不一定一致。

1.2HashSet

1.2.1HashSet是如何保证元素唯一性?

HashSet 底层数据结构是哈希表. HashSet 不是线程安全的 集合元素可以是 null ​ 哈希表:是一个元素为链表的数组,综合了数组和链表的优点 。

当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashcode()方法来得到该对象的hashcode值,然后根据hashset集合判断两个元素相等的标准:

两个对象通过hashcode()方法比较相等,并且两个对象的equals()方法返回值也相等。

即:HashSet保证元素唯一性是靠元素重写hashcode()和equals()方法来保证的。

1.2.2HashSet储存字符串并遍历

演示:

package Kscng;
 
import java.util.HashSet;
 
/*
 * HashSet:存储字符串并遍历
 */
public class MyTest1 {
    public static void main(String[] args) {
        // 创建集合对象
        HashSet<String> s = new HashSet<String>();
 
        // 创建并添加元素
        s.add("hello");
        s.add("world");
        s.add("java");
        s.add("android");
 
        // 遍历集合
        for (String i : s) {
            System.out.println(i);
        }
    }
}

1.2.3HashSet存储自定义对象并遍历

 

package westos;

import java.util.HashSet;

public class MyTest {
    public static void main(String[] args) {
        Student s1 = new Student("李一", 12);
        Student s2 = new Student("李一", 12);
        Student s3 = new Student("李三", 14);
        Student s4 = new Student("李四", 15);
        Student s5 = new Student("李五", 16);
        Student s6 = new Student("李五", 16);
        Student s7 = new Student("李六", 17);
        Student s8 = new Student("李八", 19);
        Student s9 = new Student("李八", 19);
        HashSet<Student> hashSet = new HashSet<>();
        hashSet.add(s1);
        hashSet.add(s2);
        hashSet.add(s3);
        hashSet.add(s4);
        hashSet.add(s5);
        hashSet.add(s6);
        hashSet.add(s7);
        hashSet.add(s8);
        hashSet.add(s9);
        for (Student student : hashSet) {
            System.out.println(student.getName() + "==" + student.getAge());
        }
    }
}
package westos;

import java.util.Objects;

public class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}

1.3TreeSet

1.3.1Treeset存储integer类型的元素遍历

package org.westos.demo4;

import java.util.TreeSet;

public class MyTest {
    public static void main(String[] args) {
       
        TreeSet<Integer> treeSet = new TreeSet<>();

        treeSet.add(20);
        treeSet.add(18);
        treeSet.add(23);
        treeSet.add(22);
        treeSet.add(17);
        treeSet.add(24);
        treeSet.add(19);
        treeSet.add(18);
        treeSet.add(24);
        for (Integer integer : treeSet) {
            System.out.println(integer);
        }
    }
}

注意:使用TreeSet集合进行元素的自然排序,那么对元素有要求,要求这个元素 必须实现Comparable接口 否则无法进行自然排序

1.3.2TreeSet存储自定义对象并遍历

package org.westos.demo5;

import sun.reflect.generics.tree.Tree;

import java.util.TreeSet;

public class MyTest {
    public static void main(String[] args) {
        
         Student s1 = new Student("李一", 21);
        Student s2 = new Student("李二", 21);
        Student s3 = new Student("李三", 21);
         Student s4 = new Student("李四", 22);
         Student s5 = new Student("李五", 25);
         Student s6 = new Student("李六", 25);
         Student s7 = new Student("李七", 23);
         Student s8 = new Student("李八", 25);
         Student s9 = new Student("李八", 26);
        
         TreeSet<Student> treeSet = new TreeSet<>();
        treeSet.add(s1);
        treeSet.add(s2);
        treeSet.add(s3);
        treeSet.add(s4);
        treeSet.add(s5);
        treeSet.add(s6);
        treeSet.add(s7);
        treeSet.add(s8);
        treeSet.add(s9);
        

        for (Student student : treeSet) {
            System.out.println(student);
         
        }

    }
}
package org.westos.demo5;

import java.util.Objects;

public class Student implements Comparable<Student> {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }


    @Override
    public int compareTo(Student s) {
        
        int num = this.age - s.age;
        
        int num2 = num == 0 ? this.name.compareTo(s.name) : num;
        
        return num2;
    }
}

1.3.3产生10个1-20之间的随机数要求随机数不能重复

需求:编写一个程序,获取10个1至20的随机数,要求随机数不能重复。
          并把最终的随机数输出到控制台。
          选HashSet 可以不重复
          选TreeSet 不重复还可以排序

package Kscng;

import java.util.LinkedHashSet;
import java.util.Random;

public class MyTest3 {
    public static void main(String[] args) {
        //A:
        //案例演示
        //需求:编写一个程序,获取10个1至20的随机数,要求随机数不能重复。
        Random random = new Random();

        //int num = random.nextInt(20) + 1;
        //System.out.println(num);
        LinkedHashSet<Integer> set = new LinkedHashSet<>();
        while (set.size()<10){
            int num = random.nextInt(20) + 1;
            set.add(num);
        }

        System.out.println(set);

    }
}

1.3.4键盘录入学生信息按照总分排序后输出在控制台

package shanchu;

import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;

public class MyTest2 {
    public static void main(String[] args) {
        //
        //演示:
        //需求:键盘录入3个学生信息(姓名, 语文成绩, 数学成绩, 英语成绩), 按照总分从高到低输出到控制台。
        TreeSet<Student> set = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                
                int num = s1.getzongfen() - s2.getzongfen();
                
                int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
                return -num2;
            }
        });

        for (int i = 1; i <= 3; i++) {
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入第" + i + "个学生的姓名");
            String name = sc.nextLine();
            Student student = new Student();
            student.setName(name);
            System.out.println("请输入" + name + "的语文成绩");
            int yw = sc.nextInt();
            student.setChinese(yw);

            System.out.println("请输入" + name + "的数学成绩");
            int sx = sc.nextInt();
            student.setMath(sx);

            System.out.println("请输入" + name + "的英语成绩");
            int yy = sc.nextInt();
            student.setEnglish(yy);
            
            set.add(student);
        }

        //遍历集合展示

        int index = 1;
        for (Student student : set) {
            System.out.println(index + "号" + student.getName() + "  语文成绩" + student.getChinese() + "  数学成绩" + student.getMath() + "  英语成绩" + student.getEnglish() + "  总分" + student.getzongfen());
            index++;
        }


    }
}
package shanchu;

public class Student {
    private String name;
    private int chinese;
    private int math;
    private int english;

    public Student() {
    }

    public Student(String name, int chinese, int mathe, int english) {
        this.name = name;
        this.chinese = chinese;
        this.math = math;
        this.english = english;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getChinese() {
        return chinese;
    }

    public void setChinese(int chinese) {
        this.chinese = chinese;
    }

    public int getMath() {
        return math;
    }

    public void setMath(int math) {
        this.math = math;
    }

    public int getEnglish() {
        return english;
    }

    public void setEnglish(int english) {
        this.english = english;
    }

    
    public int getzongfen() {
        return this.chinese + math + english;
    }
}

2.Map集合

2.1Map集合概念和特点

2.1.1概念

将键映射到值得对象

一个映射不能包含重复的键

每个键最多只能映射到一个值

2.1.2map接口和Collection接口的不同

Map是双列的(是双列集合的根接口)、Collection是单列的(是单列集合的根接口)。

Map的键唯一,Collection的子体系Set是唯一的。

Map集合的数据结构值针对键有效,跟值无关,Collection集合的数据结构是针对元素有效。

2.2Map集合的功能概述

2.2.1添加功能

V put(K key,V value):添加元素。

如果键是第一次存储,就直接存储元素,返回null,如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值

演示:

package westos;

import java.util.HashMap;

public class MyTest2 {
    public static void main(String[] args) {
        HashMap<String, String> map = new HashMap<>();
        String v = map.put("李一", "王一");
        System.out.println(v);
        v = map.put("李一", "王一一");
        System.out.println(v);
        map.put("李二", "王二");
        map.put("李三", "王小二");
        map.put("李四", "王三");
        map.put("李五", "王四");
        System.out.println(map);
    }
}

结果:

null
王一
{李四=王三, 李二=王二, 李三=王小二, 李五=王四, 李一=王一一}

2.2.2删除功能

void clear():移除所有的键值对元素

V remove(Object key):根据键删除键值对元素,并把值返回

演示:

package westos;

import java.util.HashMap;

public class MyTest2 {
    public static void main(String[] args) {
        HashMap<Integer, String> hashMap = new HashMap<>();
        hashMap.put(0,"aaa");
        hashMap.put(1, "bbb");
        hashMap.put(2, "ccc");
        hashMap.put(3, "ddd");
        hashMap.put(4, "eee");
        hashMap.put(5, "fff");
        
        System.out.println(hashMap);
        hashMap.remove(4);//根据键移除这个键值对

        System.out.println(hashMap);
        hashMap.clear();
        System.out.println(hashMap);
    }
}

结果:

{0=aaa, 1=bbb, 2=ccc, 3=ddd, 4=eee, 5=fff}
{0=aaa, 1=bbb, 2=ccc, 3=ddd, 5=fff}
{}

2.2.3判断功能

boolean containsKey(Object key):判断集合是否包含指定的键

boolean containsValue(Object value):判断集合是否包含指定的值

boolean isEmpty():判断集合是否为空

演示:

package westos;

import java.util.HashMap;

public class MyTest2 {
    public static void main(String[] args) {
        HashMap<Integer, String> hashMap = new HashMap<>();
        hashMap.put(1, "bbb");
        hashMap.put(2, "ccc");
        hashMap.put(3, "ddd");
        hashMap.put(4, "eee");
        hashMap.put(5, "fff");
        boolean a = hashMap.isEmpty();
        System.out.println(a);
       boolean b = hashMap.containsKey(1);
        System.out.println(b);
       boolean c = hashMap.containsValue("ccc");
        System.out.println(c);
    }
}

结果:

false
true
true

2.2.4获取功能

Set<Map.Entry<K,V>> entrySet(): 返回一个键值对的Set集合

V get(Object key):根据键获取值

Set<K> keySet():获取集合中所有键的集合

Collection<V> values():获取集合中所有值的集合

演示:

package westos;

import java.util.HashMap;

public class MyTest2 {
    public static void main(String[] args) {
        HashMap<Integer, String> hashMap = new HashMap<>();
        hashMap.put(1, "bbb");
        hashMap.put(2, "ccc");
        hashMap.put(3, "ddd");
        hashMap.put(4, "eee");
        hashMap.put(5, "fff");
        System.out.println(hashMap.entrySet());
        System.out.println(hashMap.keySet());
        System.out.println(hashMap.get(2));
        System.out.println(hashMap.values());
    }
}

结果:

[1=bbb, 2=ccc, 3=ddd, 4=eee, 5=fff]
[1, 2, 3, 4, 5]
ccc
[bbb, ccc, ddd, eee, fff]

2.2.5长度功能

int size():返回集合中的键值对的对数

演示:

package westos;

import java.util.HashMap;

public class MyTest2 {
    public static void main(String[] args) {
        HashMap<Integer, String> hashMap = new HashMap<>();
        hashMap.put(1, "bbb");
        hashMap.put(2, "ccc");
        hashMap.put(3, "ddd");
        hashMap.put(4, "eee");
        hashMap.put(5, "fff");
       int a = hashMap.size();
        System.out.println(a);
    }
}

结果:

5

2.3Map集合的遍历之键找值

package westos;

import java.util.HashMap;
import java.util.Set;

public class MyTest2 {
    public static void main(String[] args) {
        HashMap<Integer, String> hashMap = new HashMap<>();
        hashMap.put(1, "bbb");
        hashMap.put(2, "ccc");
        hashMap.put(3, "ddd");
        hashMap.put(4, "eee");
        hashMap.put(5, "fff");
        // Set<K> keySet():获取集合中所有键的集合
       Set<Integer> a =hashMap.keySet();
        for (Integer i : a) {
            System.out.println(i+"---"+hashMap.get(i));
        }
    }
}

结果:

1---bbb
2---ccc
3---ddd
4---eee
5---fff

2.4Map集合的遍历之键值对对象找键和值

package westos;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MyTest2 {
    public static void main(String[] args) {
        HashMap<Integer, String> hashMap = new HashMap<>();
        hashMap.put(1, "bbb");
        hashMap.put(2, "ccc");
        hashMap.put(3, "ddd");
        hashMap.put(4, "eee");
        hashMap.put(5, "fff");
        //boolean containsKey(Object key)
        // boolean containsValue(Object value)
        Set<Map.Entry<Integer, String>> a = hashMap.entrySet();
        for (Map.Entry<Integer, String> i : a) {
            Integer b = i.getKey();
            String c = i.getValue();
            System.out.println(b+"---"+c);
        }
    }
}

结果:

1---bbb
2---ccc
3---ddd
4---eee
5---fff

2.5HashMap集合键是Stirng值是String

package westos;

import java.util.LinkedHashMap;
import java.util.Set;


public class MyTest2 {
    public static void main(String[] args) {
        LinkedHashMap<String,String> linkedhashMap = new LinkedHashMap<>();
        linkedhashMap.put("1", "AAA");
        linkedhashMap.put("2", "BBB");
        linkedhashMap.put("3", "CCC");
        linkedhashMap.put("4", "DDD");
        linkedhashMap.put("5", "FFF");
        Set<String> str = linkedhashMap.keySet();
        for (String i : str) {
            System.out.println(i+"---"+linkedhashMap.get(i));
        }
    }
}

结果:

1---AAA
2---BBB
3---CCC
4---DDD
5---FFF

2.6HashMap 集合键是Student值是String

package shanchu;


import java.util.HashMap;


public class MyTest2 {
    public static void main(String[] args) {
        HashMap<Student, String> hashMap = new HashMap<>();
        hashMap.put(new Student("李一", 22), "1");
        hashMap.put(new Student("李二", 22), "2");
        hashMap.put(new Student("李三", 22), "3");
        hashMap.put(new Student("李四", 22), "4");
        hashMap.put(new Student("李五", 22), "5");
        hashMap.put(new Student("李六", 22), "6");
        System.out.println(hashMap);
    }
}

package shanchu;

import java.util.Objects;

public class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}

结果:

{Student{name='李三', age=22}=3, Student{name='李二', age=22}=2, Student{name='李四', age=22}=4, Student{name='李六', age=22}=6, Student{name='李一', age=22}=1, Student{name='李五', age=22}=5}

2.7TreeMap集合键是String值是String

package shanchu;

import java.util.Set;
import java.util.TreeMap;

public class MyTest2 {
    public static void main(String[] args) {

            TreeMap<Integer, String> treeMap = new TreeMap<>();
            treeMap.put(1,"aaa");
            treeMap.put(2, "bbb");
            treeMap.put(3, "ccc");
            treeMap.put(4, "ddd");
            treeMap.put(5, "eee");
            treeMap.put(6, "fff");

            Set<Integer> a = treeMap.keySet();
            for (Integer i : a) {
                System.out.println(i+"=="+treeMap.get(i));
            }
    }
}

结果:

1==aaa
2==bbb
3==ccc
4==ddd
5==eee
6==fff

2.8TreeMap集合键是Student值是String

package shanchu;

import java.util.Map;
import java.util.Set;
import java.util.TreeMap;


public class MyTest2 {
    public static void main(String[] args) {
        TreeMap<Student, String> treeMap = new TreeMap<>();
        treeMap.put(new Student("李一", 23), "1");
        treeMap.put(new Student("李二", 22), "2");
        treeMap.put(new Student("李三", 22), "3");
        treeMap.put(new Student("李四", 22), "4");
        treeMap.put(new Student("李五", 22), "5");
        treeMap.put(new Student("李六", 22), "6");
        treeMap.put(new Student("李七", 22), "7");

        Set<Map.Entry<Student, String>> entries = treeMap.entrySet();
        for (Map.Entry<Student, String> entry : entries) {
            Student key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key+"==="+value);
        }
    }
}
package shanchu;

import java.util.Objects;

public class Student implements Comparable<Student> {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    @Override
    public int compareTo(Student o) {
        int a=this.age-o.age;
        int b=a==0?this.name.compareTo(o.name):a;


        return b;
    }
}

结果:

Student{name='李七', age=22}===7
Student{name='李三', age=22}===3
Student{name='李二', age=22}===2
Student{name='李五', age=22}===5
Student{name='李六', age=22}===6
Student{name='李四', age=22}===4
Student{name='李一', age=23}===1

2.8HashMap和Hashtable的区别

主要的区别有:线程安全性,同步(synchronization),以及速度。

HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行)。

HashMap是非synchronized,而Hashtable是synchronized,这意味着Hashtable是线程安全的,多个线程可以共享一个Hashtable;

由于Hashtable是线程安全的也是synchronized,所以在单线程环境下它比HashMap要慢

3 Collections工具类的概述和常见方法讲解

3.1Collection类概念

针对集合操作的工具类

3.2Collection成员方法

public static <T> void sort(List<T> list):排序,默认按照自然顺序

public static <T> int binarySearch(List<?> list,T key):        二分查找

public static <T> T max(Collection<?> coll):                获取最大值

public static void reverse(List<?> list):                    反转

public static void shuffle(List<?> list):                        随机置换

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值