Java 基础之集合

目录

一、集合继承关系图

二、Collection 接口

三、List 接口及其实现类

四、Set接口及其实现类

五、Map接口及其实现类

六、Generics泛型

七、集合和数组工具类

八、迭代器遍历集合

九、线程安全的集合


一、集合继承关系图

        Java 集合主要分三大类,分别是List、Set、Map,而List和Set继承自Collection,整体关系如下图。        

        

另外Cellections是用来操作集合的工具类,Arrays是用来操作数组的工具类。

二、Collection 接口

        Collection 接口的主要作用是使得程序可以更方便地处理和操作集合中的对象。提供了添加、删除、遍历和查找元素的方法,以及获取集合大小和判断集合是否为空的方法。

1、add:向集合中添加指定的元素,返回是否添加成功。

2、addAll:将另一个集合中的所有元素添加到当前集合中,返回是否添加成功。

3、remove:从集合中移除指定的元素,返回是否移除成功。

4、removeAll:移除当前集合中与另一个集合中相同的所有元素,返回是否有元素被移除。

5、retainAll:仅保留与另一个集合相同的元素,移除其他元素,返回是否有元素被移除。

6、clear:清空集合,移除所有元素。

7、size:返回集合中元素的数量。

8、isEmpty:判断集合是否为空。

9、contains:判断集合是否包含指定的元素。

10、containsAll:判断集合是否包含另一个集合中的所有元素。

11、toArray:将集合中的元素转换为数组。

12、terator:返回迭代器,用于遍历集合中的元素。

13、stream():返回一个流,可用于进行流式操作。

三、List 接口及其实现类

        List接口存储一组有序、不唯一的对象。List 接口实现了动态数组(ArrayList)和链表(LinkedList)等常用数据结构,可以根据实际需求选择不同的实现类。

        List 接口的特点是可以通过索引访问和操作元素,可以按照元素的插入顺序进行遍历,允许存储重复的元素。与其他集合接口相比,List 接口更适合需要通过索引进行元素操作的场景,如需要在特定位置插入、删除元素的情况。

1、ArrayList 是一个长度可变的数组,可遍历元素和使用下标随机访问元素。

2、LinkedList 用链表存储方式实现,用于需要频繁插入和删除中间节点的操作。

3、Vector与 ArrayList 类似,但是是线程安全的,性能较差。在多线程环境中使用,或者在性能要求不高的情况下使用。

4、Stack基于 Vector 实现的栈(后进先出)数据结构。

5、CopyOnWriteArrayList 线程安全的 ArrayList 变体,适用于读多写少的场景,因为写操作会复制整个数据集。

(1)ArrayList 使用方法

        TestInfo testInfo1 = new TestInfo(1, "测试信息1");
        TestInfo testInfo2 = new TestInfo(2, "测试信息2");
        TestInfo testInfo3 = new TestInfo(3, "测试信息3");
        TestInfo testInfo4 = new TestInfo(4, "测试信息4");
        TestInfo testInfo5 = new TestInfo(5, "测试信息5");

        //创建一个ArrayList
        ArrayList list = new ArrayList();
        //添加元素
        list.add(testInfo1);//默认自动扩展长度10
        list.add(testInfo2);
        list.add(testInfo3);
        list.add(testInfo4);
        list.add(1, testInfo5);
        //删除元素
        list.remove(3);
        list.remove(testInfo2);
        //判断列表中是否包含某个元素
        if(list.contains(testInfo1)){
            System.out.println("集合包含对象 testInfo1");
        }
        else{
            System.out.println("集合不包含对象 testInfo1");
        }
        //循环查询1
        for (int index = 0; index < list.size(); index++) {
            Object obj = list.get(index);
            TestInfo testInfo = (TestInfo)obj;
            System.out.println("第一次循环输出集合元素 "+testInfo.getName());
        }
        //循环查询2
        for (Object obj : list) {
            TestInfo testInfo = (TestInfo)obj;
            System.out.println("第二次循环输出集合元素 "+testInfo.getName());
        }
        //清空集合
        list.clear();
        //判断一个集合是否为空
        if(list.isEmpty()){
            System.out.println("集合为空");
        }
        else{
            System.out.println("集合不为空");
        }

(2)LinkedList 使用方法


        TestInfo testInfo1 = new TestInfo(1, "测试信息1");
        TestInfo testInfo2 = new TestInfo(2, "测试信息2");
        TestInfo testInfo3 = new TestInfo(3, "测试信息3");
        TestInfo testInfo4 = new TestInfo(4, "测试信息4");
        TestInfo testInfo5 = new TestInfo(5, "测试信息5");

        //创建一个LinkedList
        LinkedList list = new LinkedList();
        //添加元素
        list.add(testInfo1);
        list.addFirst(testInfo2);
        list.addLast(testInfo3);
        list.addFirst(testInfo4);
        list.addLast(testInfo5);
        //删除元素
        list.removeFirst();
        //循环查询1
        for (int index = 0; index < list.size(); index++) {
            Object obj = list.get(index);
            TestInfo testInfo = (TestInfo)obj;
            System.out.println("第一次循环输出集合元素 "+testInfo.getName());
        }
        list.removeLast();
        //循环查询2
        for (Object obj : list) {
            TestInfo testInfo = (TestInfo)obj;
            System.out.println("第二次循环输出集合元素 "+testInfo.getName());
        }

(3)Vector 使用方法


        TestInfo testInfo1 = new TestInfo(1, "测试信息1");
        TestInfo testInfo2 = new TestInfo(2, "测试信息2");
        TestInfo testInfo3 = new TestInfo(3, "测试信息3");
        TestInfo testInfo4 = new TestInfo(4, "测试信息4");
        TestInfo testInfo5 = new TestInfo(5, "测试信息5");

        //创建一个 Vector
        Vector vector = new Vector();
        //添加元素
        vector.add(testInfo1);
        vector.add(testInfo2);
        vector.add(testInfo3);
        vector.add(testInfo4);
        vector.add(testInfo5);
        //删除元素
        vector.remove(testInfo1);
        //循环查询
        for (int index = 0; index < vector.size(); index++) {
            Object obj = vector.get(index);
            TestInfo testInfo = (TestInfo)obj;
            System.out.println("循环输出集合元素 "+testInfo.getName());
        }
        vector.removeAllElements();

(4)Stack使用方法


        TestInfo testInfo1 = new TestInfo(1, "测试信息1");
        TestInfo testInfo2 = new TestInfo(2, "测试信息2");
        TestInfo testInfo3 = new TestInfo(3, "测试信息3");
        TestInfo testInfo4 = new TestInfo(4, "测试信息4");
        TestInfo testInfo5 = new TestInfo(5, "测试信息5");

        //创建一个 Stack
        Stack list = new Stack();
        //添加元素
        list.push(testInfo1);
        list.push(testInfo2);
        list.push(testInfo3);
        list.push(testInfo4);
        list.push(testInfo5);
        //循环查询
        for (; list.size() > 0; ) {
            Object obj = list.pop();
            TestInfo testInfo = (TestInfo)obj;
            System.out.println("循环输出集合元素 "+testInfo.getName());
        }
        list.removeAllElements();

(5)CopyOnWriteArrayList使用方法


        TestInfo testInfo1 = new TestInfo(1, "测试信息1");
        TestInfo testInfo2 = new TestInfo(2, "测试信息2");
        TestInfo testInfo3 = new TestInfo(3, "测试信息3");
        TestInfo testInfo4 = new TestInfo(4, "测试信息4");
        TestInfo testInfo5 = new TestInfo(5, "测试信息5");

        //创建一个 CopyOnWriteArrayList
        CopyOnWriteArrayList list = new CopyOnWriteArrayList();
        //添加元素
        list.add(testInfo1);
        list.add(testInfo2);
        list.add(testInfo3);
        list.add(testInfo4);
        list.add(testInfo5);
        //删除元素
        list.remove(testInfo2);
        //循环查询1
        for (int index = 0; index < list.size(); index++) {
            Object obj = list.get(index);
            TestInfo testInfo = (TestInfo)obj;
            System.out.println("第一次循环输出集合元素 "+testInfo.getName());
        }
        //循环查询2
        for (Object obj : list) {
            TestInfo testInfo = (TestInfo)obj;
            System.out.println("第二次循环输出集合元素 "+testInfo.getName());
        }

(6)测试相关的其他类


    public static class TestInfo {
        private int id;
        private String name;

        public TestInfo(int id, String name) {
            this.id = id;
            this.name = name;
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

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


    public static class TestCompareInfo extends TestInfo implements Comparable {
        public TestCompareInfo(int id, String name) {
            super(id, name);
        }

        @Override
        public int compareTo(Object o) {
            return 0;
        }
    }

    public static class TestInfoComparator implements Comparator<TestInfo> {
        @Override
        public int compare(TestInfo t1, TestInfo t2) {
            return Integer.compare(t1.getId(), t2.getId());
        }
    }

四、Set接口及其实现类

        Set接口存储一组无序、唯一的对象。它是处理去重数据的常用选择,并提供了高效的查找和判断元素存在性的功能。常见的 Set 接口的实现类包括 HashSet、TreeSet 和 LinkedHashSet 等。

1、HashSet 基于散列表(哈希表)实现,存储唯一元素,不保证元素的顺序。      

2、LinkedHashSet 在 HashSet 的基础上,使用链表维护插入顺序,因此能够保持插入顺序。

3、TreeSet 基于红黑树实现,存储唯一元素,并按照元素的自然顺序(或者提供的比较器)进行排序。

3、EnumSet:专门用于存储枚举类型的集合,基于位向量实现,非常高效。

4、CopyOnWriteArraySet 线程安全的 Set 变体,底层基于 CopyOnWriteArrayList,适用于读多写少的场景。

 (1)HashSet使用方法


        TestInfo testInfo1 = new TestInfo(1, "测试信息1");
        TestInfo testInfo2 = new TestInfo(2, "测试信息2");
        TestInfo testInfo3 = new TestInfo(3, "测试信息3");
        TestInfo testInfo4 = new TestInfo(4, "测试信息4");
        TestInfo testInfo5 = new TestInfo(5, "测试信息5");

        //创建一个HashSet
        HashSet set = new HashSet();
        //添加元素
        set.add(testInfo1);
        set.add(testInfo2);
        set.add(testInfo3);
        set.add(testInfo4);
        set.add(testInfo5);

        set.add(testInfo1);
        set.add(testInfo1);
        set.add(testInfo2);
        //删除元素
        set.remove(testInfo5);

        //循环查询
        for (Object obj : set) {
            TestInfo testInfo = (TestInfo)obj;
            System.out.println("循环输出集合元素 "+testInfo.getName());
        }

(2)LinkedHashSet使用方法


        TestInfo testInfo1 = new TestInfo(1, "测试信息1");
        TestInfo testInfo2 = new TestInfo(2, "测试信息2");
        TestInfo testInfo3 = new TestInfo(3, "测试信息3");
        TestInfo testInfo4 = new TestInfo(4, "测试信息4");
        TestInfo testInfo5 = new TestInfo(5, "测试信息5");

        //创建一个 HashSet
        LinkedHashSet set = new LinkedHashSet();
        //添加元素
        set.add(testInfo1);
        set.add(testInfo2);
        set.add(testInfo3);
        set.add(testInfo4);
        set.add(testInfo5);

        set.add(testInfo1);
        set.add(testInfo1);
        set.add(testInfo2);
        //删除元素
        set.remove(testInfo5);

        //循环查询
        for (Object obj : set) {
            TestInfo testInfo = (TestInfo)obj;
            System.out.println("循环输出集合元素 "+testInfo.getName());
        }

(3)TreeSet使用方法


        TestInfo testInfo1 = new TestInfo(1, "测试信息1");
        TestInfo testInfo2 = new TestInfo(2, "测试信息2");
        TestInfo testInfo3 = new TestInfo(3, "测试信息3");
        TestInfo testInfo4 = new TestInfo(4, "测试信息4");
        TestInfo testInfo5 = new TestInfo(5, "测试信息5");

        TestInfoComparator comparator = new TestInfoComparator();
        //创建一个TreeSet
        TreeSet set = new TreeSet(comparator);//这里如果不传入comparator, 添加的对象就要使用类似于TestCompareInfo的类
        //添加元素
        set.add(testInfo1);
        set.add(testInfo2);
        set.add(testInfo3);
        set.add(testInfo4);
        set.add(testInfo5);


        set.add(testInfo1);
        set.add(testInfo1);
        set.add(testInfo2);
        //删除元素
        set.remove(testInfo5);


        //循环查询
        for (Object obj : set) {
            TestInfo testInfo = (TestInfo)obj;
            System.out.println("循环输出集合元素 "+testInfo.getName());
        }

(4)EnumSet使用方法


        //1、创建 EnumSet

        // 创建一个包含所有枚举值的 EnumSet
        EnumSet<Weekday> set1 = EnumSet.allOf(Weekday.class);
        // 创建一个空的 EnumSet,并指定枚举类型
        EnumSet<Weekday> set2 = EnumSet.noneOf(Weekday.class);
        // 创建一个包含指定枚举值的 EnumSet
        EnumSet<Weekday> set3 = EnumSet.of(Weekday.SATURDAY, Weekday.SUNDAY);
        // 创建一个范围内的 EnumSet,包含起始和结束之间的所有枚举值:
        EnumSet<Weekday> set4 = EnumSet.range(Weekday.MONDAY, Weekday.FRIDAY);


        // 2、添加和删除元素

        EnumSet<Weekday> set5 = EnumSet.noneOf(Weekday.class);
        // 添加一个枚举值到 EnumSet:
        set5.add(Weekday.MONDAY);
        set5.add(Weekday.TUESDAY);
        set5.add(Weekday.WEDNESDAY);
        // 删除一个枚举值从 EnumSet:
        set5.remove(Weekday.MONDAY);

        // 3、检查元素是否存在
        // 检查 EnumSet 是否包含指定枚举值
        boolean contains = set5.contains(Weekday.MONDAY);

        // 4、大小和清空操作
        // 获取 EnumSet 的大小(包含的枚举值数量)
        int size = set5.size();
        // 清空 EnumSet 中的所有元素:
        // set5.clear();

        // 5、遍历 EnumSet

        // 使用迭代器遍历 EnumSet:
        Iterator<Weekday> iterator = set5.iterator();
        while (iterator.hasNext()) {
            Weekday value = iterator.next();
            System.out.println(value);
        }

        // 使用增强的 for 循环遍历 EnumSet:
        for (Weekday value : set5) {
            System.out.println(value);
        }

(5)CopyOnWriteArraySet使用方法


        TestInfo testInfo1 = new TestInfo(1, "测试信息1");
        TestInfo testInfo2 = new TestInfo(2, "测试信息2");
        TestInfo testInfo3 = new TestInfo(3, "测试信息3");
        TestInfo testInfo4 = new TestInfo(4, "测试信息4");
        TestInfo testInfo5 = new TestInfo(5, "测试信息5");

        //创建一个 CopyOnWriteArraySet
        CopyOnWriteArraySet set = new CopyOnWriteArraySet();
        //添加元素
        set.add(testInfo1);
        set.add(testInfo2);
        set.add(testInfo3);
        set.add(testInfo4);
        set.add(testInfo5);

        set.add(testInfo1);
        set.add(testInfo1);
        set.add(testInfo2);
        //删除元素
        set.remove(testInfo5);

        //循环查询
        for (Object obj : set) {
            TestInfo testInfo = (TestInfo)obj;
            System.out.println("循环输出集合元素 "+testInfo.getName());
        }

    public static class TestInfo {
        private int id;
        private String name;

        public TestInfo(int id, String name) {
            this.id = id;
            this.name = name;
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

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


    public static class TestCompareInfo extends TestInfo implements Comparable {
        public TestCompareInfo(int id, String name) {
            super(id, name);
        }

        @Override
        public int compareTo(Object o) {
            return 0;
        }
    }

    public static class TestInfoComparator implements Comparator<TestInfo> {
        @Override
        public int compare(TestInfo t1, TestInfo t2) {
            return Integer.compare(t1.getId(), t2.getId());
        }
    }

    public enum Weekday {
        MONDAY,
        TUESDAY,
        WEDNESDAY,
        THURSDAY,
        FRIDAY,
        SATURDAY,
        SUNDAY
    }

五、Map接口及其实现类

        用于存储键值对(key-value)的数据结构。Map 接口提供了一种将键映射到值的方式,它不允许键重复,并且可以根据键快速找到对应的值。常见的 Map 接口的实现类包括 HashMap、TreeMap 和 LinkedHashMap 等。

1、HashMap 基于散列表(哈希表)实现,存储键值对,键是唯一的。不保证键值对的顺序。

2、LinkedHashMap 在 HashMap 的基础上,使用链表维护插入顺序或访问顺序,能够保持插入顺序或按照访问顺序遍历键值对。

3、TreeMap 基于红黑树实现,存储键值对,并按照键的自然顺序(或者提供的比较器)进行排序

4、WeakHashMap 与 HashMap 类似,但对于没有被其他对象引用的键,不会阻止垃圾回收。

5、EnumMap 专门用于存储枚举类型的键的集合,内部基于数组实现,非常高效。

6、IdentityHashMap 使用引用相等而不是值相等来比较键,对于对象引用的比较非常严格。

7、ConcurrentHashMap线程安全的 HashMap 变体,支持并发访问,分段锁机制提高了并发性能。

8、Properties一个特殊的 Map 实现,用于处理属性文件,键和值都必须为字符串类型。

9、HashTable 与 HashMap 类似,但是是线程安全的,性能较差。在多线程环境中使用,或者在性能要求不高的情况下使用。

 (1)HashMap使用方法


        TestInfo testInfo1 = new TestInfo(1, "测试信息1");
        TestInfo testInfo2 = new TestInfo(2, "测试信息2");
        TestInfo testInfo3 = new TestInfo(3, "测试信息3");
        TestInfo testInfo4 = new TestInfo(4, "测试信息4");
        TestInfo testInfo5 = new TestInfo(5, "测试信息5");

        //创建一个 HashMap
        HashMap map = new HashMap();
        //添加元素
        map.put(testInfo1.getId(), testInfo1);
        map.put(testInfo2.getId(), testInfo2);
        map.put(testInfo3.getId(), testInfo3);
        map.put(testInfo4, testInfo4);
        map.put(testInfo5, testInfo5);

        map.put(testInfo5.getId(), testInfo5);

        //删除元素
        map.remove(testInfo3.getId());


        //根据Key循环查询
        Set keys = map.keySet();
        for (Object obj : keys) {
            TestInfo testInfo = null;
            if(obj instanceof Integer){
                int id = (int)obj;
                testInfo = (TestInfo)map.get(id);
            }
            else{
                testInfo = (TestInfo)obj;
            }
            System.out.println("根据Key 循环输出元素 "+testInfo.getName());
        }

        //根据entry循环查询
        Set entry = map.entrySet();
        for (Object obj : entry) {
            Map.Entry me = (Map.Entry)obj;
            Object key = me.getKey();
            TestInfo testInfo = (TestInfo)me.getValue();
            System.out.println("根据Entry 循环输出元素 "+testInfo.getName());
        }

(2)LinkedHashMap使用方法


        TestInfo testInfo1 = new TestInfo(1, "测试信息1");
        TestInfo testInfo2 = new TestInfo(2, "测试信息2");
        TestInfo testInfo3 = new TestInfo(3, "测试信息3");
        TestInfo testInfo4 = new TestInfo(4, "测试信息4");
        TestInfo testInfo5 = new TestInfo(5, "测试信息5");

        //创建一个 LinkedHashMap
        LinkedHashMap map = new LinkedHashMap();
        //添加元素
        map.put(testInfo1.getId(), testInfo1);
        map.put(testInfo2.getId(), testInfo2);
        map.put(testInfo3.getId(), testInfo3);
        map.put(testInfo4.getId(), testInfo4);
        map.put(testInfo5.getId(), testInfo5);

        //map.put(testInfo5, testInfo5);   混合添加不能再使用,因为他要排序

        //删除元素
        map.remove(testInfo3.getId());


        //根据Key循环查询
        Set keys = map.keySet();
        for (Object obj : keys) {
            int id = (int)obj;
            TestInfo testInfo = (TestInfo)map.get(id);
            System.out.println("根据Key 循环输出元素 "+testInfo.getName());
        }

        //根据entry循环查询
        Set entry = map.entrySet();
        for (Object obj : entry) {
            Map.Entry me = (Map.Entry)obj;
            int key = (int)me.getKey();
            TestInfo testInfo = (TestInfo)me.getValue();
            System.out.println("根据Entry 循环输出元素 "+testInfo.getName());
        }

(3)TreeMap使用方法


        TestInfo testInfo1 = new TestInfo(1, "测试信息1");
        TestInfo testInfo2 = new TestInfo(2, "测试信息2");
        TestInfo testInfo3 = new TestInfo(3, "测试信息3");
        TestInfo testInfo4 = new TestInfo(4, "测试信息4");
        TestInfo testInfo5 = new TestInfo(5, "测试信息5");

        //创建一个 TreeMap
        TreeMap map = new TreeMap();
        //添加元素
        map.put(testInfo1.getId(), testInfo1);
        map.put(testInfo2.getId(), testInfo2);
        map.put(testInfo3.getId(), testInfo3);
        map.put(testInfo4.getId(), testInfo4);
        map.put(testInfo5.getId(), testInfo5);

        map.put(testInfo5.getId(), testInfo5);
        //map.put(testInfo5, testInfo5);   混合添加不能再使用,因为他要排序

        //删除元素
        map.remove(testInfo3.getId());


        //根据Key循环查询
        Set keys = map.keySet();
        for (Object obj : keys) {
            int id = (int)obj;
            TestInfo testInfo = (TestInfo)map.get(id);
            System.out.println("根据Key 循环输出元素 "+testInfo.getName());
        }

        //根据entry循环查询
        Set entry = map.entrySet();
        for (Object obj : entry) {
            Map.Entry me = (Map.Entry)obj;
            int key = (int)me.getKey();
            TestInfo testInfo = (TestInfo)me.getValue();
            System.out.println("根据Entry 循环输出元素 "+testInfo.getName());
        }

(4)WeakHashMap使用方法


        TestInfo testInfo1 = new TestInfo(1, "测试信息1");
        TestInfo testInfo2 = new TestInfo(2, "测试信息2");
        TestInfo testInfo3 = new TestInfo(3, "测试信息3");
        TestInfo testInfo4 = new TestInfo(4, "测试信息4");
        TestInfo testInfo5 = new TestInfo(5, "测试信息5");

        //创建一个 WeakHashMap
        WeakHashMap map = new WeakHashMap ();
        //添加元素
        map.put(testInfo1.getId(), testInfo1);
        map.put(testInfo2.getId(), testInfo2);
        map.put(testInfo3.getId(), testInfo3);
        map.put(testInfo4, testInfo4);
        map.put(testInfo5, testInfo5);

        map.put(testInfo5.getId(), testInfo5);

        //删除元素
        map.remove(testInfo3.getId());


        //根据Key循环查询
        Set keys = map.keySet();
        for (Object obj : keys) {
            TestInfo testInfo = null;
            if(obj instanceof Integer){
                int id = (int)obj;
                testInfo = (TestInfo)map.get(id);
            }
            else{
                testInfo = (TestInfo)obj;
            }
            System.out.println("根据Key 循环输出元素 "+testInfo.getName());
        }

        //根据entry循环查询
        Set entry = map.entrySet();
        for (Object obj : entry) {
            Map.Entry me = (Map.Entry)obj;
            Object key = me.getKey();
            TestInfo testInfo = (TestInfo)me.getValue();
            System.out.println("根据Entry 循环输出元素 "+testInfo.getName());
        }

(5)EnumMap使用方法


        // 1、创建 EnumMap

        // 创建一个空的 EnumMap,并指定枚举类型
        EnumMap<Weekday, Integer> map1 = new EnumMap<>(Weekday.class);

        // 2、添加和更新键值对

        // 添加一个键值对到 EnumMap
        map1.put(Weekday.MONDAY, 10);
        map1.put(Weekday.TUESDAY, 2);
        map1.put(Weekday.WEDNESDAY, 3);
        // 更新一个键对应的值
        map1.put(Weekday.MONDAY, 1);

        // 3、获取和删除键值对

        // 获取指定键对应的值
        Integer value1 = map1.get(Weekday.MONDAY);
        // 删除指定键对应的键值对
        map1.remove(Weekday.MONDAY);

        // 4、检查键是否存在

        // 检查 EnumMap 是否包含指定键
        boolean containsKey = map1.containsKey(Weekday.MONDAY);

        // 5、大小和清空操作

        // 获取 EnumMap 中键值对的数量
        int size = map1.size();
        // 清空 EnumMap 中的所有键值对
        // map1.clear();

        // 6、遍历键值对

        // 使用迭代器遍历 EnumMap 的键值对
        Iterator<Map.Entry<Weekday, Integer>> iterator = map1.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<Weekday, Integer> entry = iterator.next();
            Weekday key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println("key="+key+",value="+value);
        }
        // 使用增强的 for 循环遍历 EnumMap 的键值对
        for (Map.Entry<Weekday, Integer> entry : map1.entrySet()) {
            Weekday key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println("key="+key+",value="+value);
        }

 (6)IdentityHashMap使用方法


        TestInfo testInfo1 = new TestInfo(1, "测试信息1");
        TestInfo testInfo2 = new TestInfo(2, "测试信息2");
        TestInfo testInfo3 = new TestInfo(3, "测试信息3");
        TestInfo testInfo4 = new TestInfo(4, "测试信息4");
        TestInfo testInfo5 = new TestInfo(5, "测试信息5");

        //创建一个 IdentityHashMap
        IdentityHashMap map = new IdentityHashMap ();
        //添加元素
        map.put(testInfo1.getId(), testInfo1);
        map.put(testInfo2.getId(), testInfo2);
        map.put(testInfo3.getId(), testInfo3);
        map.put(testInfo4, testInfo4);
        map.put(testInfo5, testInfo5);

        map.put(testInfo5.getId(), testInfo5);

        //删除元素
        map.remove(testInfo3.getId());


        //根据Key循环查询
        Set keys = map.keySet();
        for (Object obj : keys) {
            TestInfo testInfo = null;
            if(obj instanceof Integer){
                int id = (int)obj;
                testInfo = (TestInfo)map.get(id);
            }
            else{
                testInfo = (TestInfo)obj;
            }
            System.out.println("根据Key 循环输出元素 "+testInfo.getName());
        }

        //根据entry循环查询
        Set entry = map.entrySet();
        for (Object obj : entry) {
            Map.Entry me = (Map.Entry)obj;
            Object key = me.getKey();
            TestInfo testInfo = (TestInfo)me.getValue();
            System.out.println("根据Entry 循环输出元素 "+testInfo.getName());
        }

 (7)ConcurrentHashMap使用方法


        TestInfo testInfo1 = new TestInfo(1, "测试信息1");
        TestInfo testInfo2 = new TestInfo(2, "测试信息2");
        TestInfo testInfo3 = new TestInfo(3, "测试信息3");
        TestInfo testInfo4 = new TestInfo(4, "测试信息4");
        TestInfo testInfo5 = new TestInfo(5, "测试信息5");

        //创建一个 ConcurrentHashMap
        ConcurrentHashMap map = new ConcurrentHashMap ();
        //添加元素
        map.put(testInfo1.getId(), testInfo1);
        map.put(testInfo2.getId(), testInfo2);
        map.put(testInfo3.getId(), testInfo3);
        map.put(testInfo4, testInfo4);
        map.put(testInfo5, testInfo5);

        map.put(testInfo5.getId(), testInfo5);

        //删除元素
        map.remove(testInfo3.getId());


        //根据Key循环查询
        Set keys = map.keySet();
        for (Object obj : keys) {
            TestInfo testInfo = null;
            if(obj instanceof Integer){
                int id = (int)obj;
                testInfo = (TestInfo)map.get(id);
            }
            else{
                testInfo = (TestInfo)obj;
            }
            System.out.println("根据Key 循环输出元素 "+testInfo.getName());
        }

        //根据entry循环查询
        Set entry = map.entrySet();
        for (Object obj : entry) {
            Map.Entry me = (Map.Entry)obj;
            Object key = me.getKey();
            TestInfo testInfo = (TestInfo)me.getValue();
            System.out.println("根据Entry 循环输出元素 "+testInfo.getName());
        }

六、Generics泛型

        Java 泛型是一种强大的编程机制,它允许你在创建类、接口和方法时定义参数类型,从而实现类型安全和代码重用。

         给集添加泛型约束的举例:

    
    public static void main(String[] args) {

        TestInfo testInfo1 = new TestInfo(1, "测试信息1");
        TestInfo testInfo2 = new TestInfo(2, "测试信息2");
        TestInfo testInfo3 = new TestInfo(3, "测试信息3");
        TestInfo testInfo4 = new TestInfo(4, "测试信息4");
        TestInfo testInfo5 = new TestInfo(5, "测试信息5");
        TestCompareInfo testInfo6 = new TestCompareInfo(6, "测试信息5");
        TestCompareInfo testInfo7 = new TestCompareInfo(7, "测试信息5");

        TestInfoComparator comparator = new TestInfoComparator();

        List list1 = new ArrayList<TestInfo>();
        List list2 = new LinkedList<TestInfo>();
        Set set1 = new HashSet<TestInfo>();
        Set set2 = new TreeSet<TestInfo>();
        Map<Integer, TestInfo> map1 = new HashMap<Integer, TestInfo>();
        Map<Integer, TestInfo> map2 = new LinkedHashMap<Integer, TestInfo>();
        Map<Integer, TestInfo> map3 = new TreeMap<Integer, TestInfo>();
        //使用传入比较器的 TreeMap
        Map<TestInfo, TestInfo> map4 = new TreeMap<TestInfo, TestInfo>(comparator);
        Map<TestInfo, TestInfo> map5 = new TreeMap<TestInfo, TestInfo>(comparator);
        //使用实现比较接口的 TreeMap
        Map<TestCompareInfo, TestInfo> map6 = new TreeMap<TestCompareInfo, TestInfo>();
        Map<TestCompareInfo, TestInfo> map7 = new TreeMap<TestCompareInfo, TestInfo>();


        map1.put(testInfo1.getId(), testInfo1);
        map2.put(testInfo2.getId(), testInfo2);
        map3.put(testInfo3.getId(), testInfo3);
        map4.put(testInfo4, testInfo4);
        map5.put(testInfo5, testInfo4);
        map6.put(testInfo6, testInfo6);
        map7.put(testInfo7, testInfo7);

        Set<Map.Entry<Integer, TestInfo>> entries = map1.entrySet();
    }

    public static class TestInfo {
        private int id;
        private String name;

        public TestInfo(int id, String name) {
            this.id = id;
            this.name = name;
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

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

    public static class TestCompareInfo extends TestInfo implements Comparable {
        public TestCompareInfo(int id, String name) {
            super(id, name);
        }

        @Override
        public int compareTo(Object o) {
            return 0;
        }
    }

    public static class TestInfoComparator implements Comparator<TestInfo> {
        @Override
        public int compare(TestInfo t1, TestInfo t2) {
            return Integer.compare(t1.getId(), t2.getId());
        }
    }

七、集合和数组工具类

        1、Collections 工具类

(1)sort:对列表进行排序。

(2)binarySearch:在已排序的列表中使用二分查找来查找指定的元素。

(3)reverse:反转列表中元素的顺序。

(4)shuffle:随机重排列表中的元素。

(5)min:返回集合中的最小元素。

(6)max:返回集合中的最大元素。

(7)unmodifiableList:返回一个不可修改的列表视图。

(8)synchronizedMap:返回一个线程安全的映射。

(9)ingleton:返回一个包含单个指定对象的不可修改的集合。

(10)emptyList:返回一个空的不可修改的列表。

(11)emptySet:返回一个空的不可修改的集合。


        TestCompareInfo testInfo1 = new TestCompareInfo(1, "测试信息1");
        TestCompareInfo testInfo2 = new TestCompareInfo(2, "测试信息2");
        TestCompareInfo testInfo3 = new TestCompareInfo(3, "测试信息3");
        TestCompareInfo testInfo4 = new TestCompareInfo(4, "测试信息4");
        TestCompareInfo testInfo5 = new TestCompareInfo(5, "测试信息5");

        List<TestCompareInfo> list = new ArrayList<TestCompareInfo>();
        list.add(testInfo1);
        list.add(testInfo2);
        list.add(testInfo3);
        list.add(testInfo4);
        list.add(testInfo5);

        //Collections.sort(list);
        System.out.println("最小值 "+ Collections.min(list).getName());
        System.out.println("最大值 "+ Collections.max(list).getName());

        System.out.println("搜索 testInfo3 位置 = "+ Collections.binarySearch(list, testInfo3));

        // 返回包含指定元素的不可变 List。
        // Collections.nCopies();

        // 返回只包含一个指定元素的不可变 List。
        // Collections.singletonList()

        // 返回只包含一个指定元素的不可变 Set。
        // Collections.singleton()

        // 返回空的不可变 Set。
        // Collections.emptySet()

        2、Arrays工具类

(1)sort:对数组进行排序。

(2)binarySearch:在已排序的数组中使用二分查找来查找指定的元素。

(3)fill:将数组中的所有元素填充为指定的值。

(4)copyOfRange:复制原始数组的指定范围部分,生成一个新的数组。

(5)equals:判断两个数组是否相等。

(6)asList:将指定的元素转换为固定大小的列表。


        TestCompareInfo testInfo1 = new TestCompareInfo(1, "测试信息1");
        TestCompareInfo testInfo2 = new TestCompareInfo(2, "测试信息2");
        TestCompareInfo testInfo3 = new TestCompareInfo(3, "测试信息3");
        TestCompareInfo testInfo4 = new TestCompareInfo(4, "测试信息4");
        TestCompareInfo testInfo5 = new TestCompareInfo(5, "测试信息5");

        List<TestCompareInfo> list = new ArrayList<TestCompareInfo>();
        list.add(testInfo3);
        list.add(testInfo1);
        list.add(testInfo4);
        list.add(testInfo2);
        list.add(testInfo5);


        // 转换为数组
        TestCompareInfo[] array = list.toArray(new TestCompareInfo[0]);
        // 使用 Arrays.sort 对数组进行排序
        Arrays.sort(array);
        // 转换回 ArrayList
        ArrayList<TestCompareInfo> sortedList = new ArrayList<>(Arrays.asList(array));

        //循环查询2
        for (TestCompareInfo testInfo : sortedList) {
            System.out.println("排序后结果 "+testInfo.getName());
        }

        // 将数组转换为固定大小的 List,不支持插入和删除操作。
        List list1 = Arrays.asList(new int[]{ 1, 2 ,3, 4, 4});

八、迭代器遍历集合

        Iterator 提供了一种安全、抽象化的遍历方式,适用于多种集合实现,同时支持元素的移除操作,使代码更加健壮和清晰。主要优势如下:

(1)安全遍历集合: Iterator 提供了一种安全的方式来遍历集合,尤其在多线程环境中,可以避免遍历过程中的并发修改问题。遍历过程中如果尝试修改集合,会抛出 ConcurrentModificationException 异常,从而提醒开发者注意并发问题。

(2)支持移除元素: Iterator 提供了 remove() 方法,允许你在遍历过程中删除集合中的元素。这是使用增强 for 循环无法实现的功能,可以避免在遍历过程中删除元素时引发的问题。

(3)抽象化遍历方式: 使用 Iterator 可以将遍历逻辑与具体的集合实现分离,使你能够以一种统一的方式遍历不同类型的集合,无论是数组、列表、集或映射。

(4)避免索引操作: 使用 Iterator 可以避免使用索引进行遍历,从而使代码更加清晰,不会因索引操作而引入错误。

(5)遍历途中插入元素: 使用 Iterator 遍历集合时,可以在遍历过程中插入新元素,而不会影响当前遍历的内容。这是在使用增强 for 循环时无法做到的。


        TestInfo testInfo1 = new TestInfo(1, "测试信息1");
        TestInfo testInfo2 = new TestInfo(2, "测试信息2");
        TestInfo testInfo3 = new TestInfo(3, "测试信息3");
        TestInfo testInfo4 = new TestInfo(4, "测试信息4");
        TestInfo testInfo5 = new TestInfo(5, "测试信息5");

        ArrayList list = new ArrayList();
        list.add(testInfo1);
        list.add(testInfo2);
        list.add(testInfo3);
        list.add(testInfo4);
        list.add(testInfo5);

        Iterator itor = list.iterator();
        while(itor.hasNext()){
            Object obj = itor.next();
            TestInfo testInfo = (TestInfo)obj;
            System.out.println("第二次循环输出集合元素 "+testInfo.getName());
        }

九、线程安全的集合

         线程安全的集合类在java.util.concurrent包下面,他们提供了在多线程环境下安全地进行操作的方式,可以根据具体的需求选择适合的集合类来使用。使用方法与普通集合差不大,请参考普通集全使用方法。

        需要注意的是,虽然这些集合类提供了线程安全的操作,但在特定的场景下可能需要额外的同步措施,以确保操作的原子性和一致性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

QIFU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值