Java集合学习随笔

1 引言

​ 一个没用的东西,学了等于没学,那还学个啥?下面,我们先分析集合的好处,知其所以然在知其然

1.1 集合解决了什么问题

​ 前面我们学习了数组,当我们使用数组时,必须指定数组的长度。假设我们在使用数组时,预估了存入数组的大小,指定了数组的长度,但是,实际操作中发现数组的长度不够了,怎么办?

​ 唉,如果这时候能有个长度随时能变的“数组”就好了。

​ 哈哈,你还别说,真就有个这么个类似能灵活的改变数组长度的东西,叫集合。他能解决数组长度不够的问题。说到这里,就得感谢前辈们的辛苦付出了,前人栽树后人乘凉

1.2 集合的好处

​ (1)集合的长度是可以改变的,集合可以按照一定规律扩容。

​ (2)集合的实现类很多,有能存储重复元素的集合,也有存储不重复数据的集合,提供多种选择。

​ (3)可以用选择排序器和定制排序器对集合中的数据进行一定规律的排序。

​ (4)可以简单快速的查询集合中的数据。

​ (5)集合具有映射关系,比如,在双列集合中,我们通过Key值可以找到它对应的value值,并且Key值可以是任意数据类型

​ (6)删除、改变数据很方便。

​ (7)…

2 集合闪亮登场

2.1 什么是集合

​ Java是一门面向对象的语言,就免不了处理对象,为了方便操作多个对象,那么我们就得把这多个对象存储起来,想要存储多个对象(变量),很容易就能想到一个容器(集合)来装载。

集合是指具有某种特定性质的具体的或抽象的对象汇总而成的集体。

​ 通俗的说,很多个数据(可以是同种类型的也可以是不同种类型的)都存储到一个容器中,而这个容器就是集合。

2.2 集合都有哪些

​ 1 集合有很多,但我们主要研究Collection集合和Map集合还有Collections工具类,Collection又包括Lise和Set,Map包括HashMap和TreeMap等等。见下图集合的关系图:

在这里插入图片描述

​ 2 IEDA中的类和接口的关系如下:

​ 2.1 Colledfction接口:

在这里插入图片描述

注:蓝色实线表示指向父类(继承关系),绿色虚线表示指向父类接口(实现关系),绿色实线表示实现接口或继承父类的关系(关联关系),灰色虚线无带字说明的表示调用关系(箭头背向的调用箭头指向的),虚线中带字说明的,箭头背向的创建了箭头指向的类。

2.2 Map接口
在这里插入图片描述

​ 3 集合思维导图如下

在这里插入图片描述

注:红色的为接口,绿色的为实现类。

3 Collection接口

​ Collection接口有两个子接口List和Set,他们实现的都是单列集合。

3.1 Collection接口的特点

​ (1)有些Collection实现子类可以存放多个数据,每个数据类型可以不同也可以相同。

​ (2)有些Collection的实现类,可以存放重复的数据,有些不能存放重复的数据。

​ (3)有些Collection的实现类,有些是有序的(List),有些是无序的(Set).

​ (4)Collection接口没有直接的实现子类,是通过它的子接口Set和list接口的实现类实现的。

3.2 Collection接口的方法

​ (1) 添加

		add(Object obj)

​ addAll(Collection coll)

​ (2)获取有效元素的个数

		int size()

​ (3)清空集合

		void clear()

​ (4)是否是空集合

		boolean isEmpty()

​ (5)是否包含某个元素

		boolean contains(Object obj): 是通过元素的equals方法来判断是否是同一个对象

​ boolean containsAll(Collection c): 也是调用元素的equals方法来比较的。 拿两个集合的元素挨个比较。

​ (6)删除

		boolean remove(Object obj) : 通过元素的equals方法判断是否是要删除的那个元素。 只会删除找到的第一个元素

​ boolean removeAll(Collection coll): 取当前集合的差集

​ (7)取两个集合的交集

		boolean retainAll(Collection c): 把交集的结果存在当前集合中,不影响c

​ (8)集合是否相等

		boolean equals(Object obj)

​ (9)转成对象数组

		Object[] toArray()

​ (10)遍历

		iterator(): 返回迭代器对象,用于集合遍历 、

3.3 Collection接口遍历元素方式

3.3.1Iterator迭代器
3.3.1.1 什么是Iterator迭代器

(1)Iterator对象称为迭代器(设计模式的一种),主要用于遍历 Collection 集合中的元素。

(2)GOF给迭代器模式的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。 迭代器模式,就是为容器而生。 类似于“公交车上的售票员”、“火车上的乘务员”、 “空姐” 。

(3)从上面IDEA中的Collection关系图中可以看到,Collection接口用绿色的实线指向了Iterables,这个接口就可以实现迭代器。

3.3.1.2 Iterator迭代器特点

(1)Collection接口继承了java.lang.Iterable接口,该接口有一个iterator()方法,那么所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象。

(2)Iterator 仅用于遍历集合, Iterator 本身并不提供承装对象的能力。如果需要创建Iterator 对象,则必须有一个被迭代的集合。

(3)集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。

3.3.1.3 Iterator迭代器使用和原理
       Iterator iterator = list.iterator(); //得到一个集合的迭代器
        
        while (iterator.hasNext()) {         //has,next():判断是否还有下一个元素
        
            Object next = iterator.next();   //iterator.next():指针下移并将下移以                                              //后集合的位置返回上一个元素返回
            
            System.out.println(next);        //输出元素
        }

注意:当执行完上面的代码后,迭代器的指针已经指向集合的最后一个元素,迭代器指针不会自动返回到初始位置,如果想再次遍历集合,需要重置遍历器Iterator = list.iterator()或者新建一个迭代器Iterator newIterator = list.iterator()进行遍历。

见下图

在这里插入图片描述

实例见下面的LinkedList类。

3.3.2 增强for循环

增强for循环,可以替代iterator迭代器,其实就是简化的迭代器,本质一样,只能用来遍历集合和数组。

3.3.2.1 基本语法
for(元素类型 元素名 : 集合或数组名){

				输出元素

}

实例见下面的ArrayList类。

3.4 List接口

​ List接口继承了Collection接口,List接口的实现类存储数据可以重复,它的实现类主要有三个,分别为ArrayList类、LinkedList类、Vector类。

3.4.1 ArrayList类
3.4.1.1 ArrayList类集合特点

​ (1)ArrayList类实现了List接口,Collection接口的方法都可以使用。

​ (2)ArrayList集合对数据类型没有要求,可以放多个null元素。

​ (3)ArrayList是线程不安全的(多线程不推荐使用),但执行效率高。

在这里插入图片描述

​ (4)ArrayList是由数组实现数据存储的。

​ (5)数据可以重复,数据是有序的,存储顺序就是插入顺序。

3.4.1.2 ArrayList集合扩容原理

​ (1)ArrayList其实是一个Object类型的elementDate数组

​ (2)当创建ArrayList集合时,如果没有初始化容量,则调用的是无参构造器,则初始容量为0,第一次添加元素,则容量扩容为10,以后需要扩容都是扩容上一次容量的1.5倍。

​ (2)当创建ArrayList集合时,如果设置初始化容量,则调用的是有参构造器,则初始容量为指定的容量,以后需要扩容都是扩容上一个容量的1.5倍。

3.4.1.3 练习
public class ArrayLIstDemo {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("北京");
        list.add("天津");
        list.add("北京");
        list.add("天津");
        list.add("ABC");
        list.add(123); // 当存入int类型数据时,集合会将int类型的数据自动装箱成Integer
        list.add(456);
        list.add(456);
        list.add(new Date());
        System.out.println(list);
        System.out.println("******************************");

        //增强for循环遍历
        for (Object o : list) {
            System.out.println(o);
        }
    }
}

结果如下:

在这里插入图片描述

3.4.2 LinkedList类

LinkedList类实现了List接口,Collection接口的方法都可以使用。

3.4.2.1 LinkedList集合特点

​ (1)LinkedLIst实现了双向链表。

​ (2)可以添加任意元素。

​ (3)LinkedList类实现了List接口,Collection接口的方法都可以使用。

​ (4)LinkedList是线程不安全的。

3.4.2.2 LinkedList存储原理

LinkedList实现的是一个双向链表,当向里面存储元素时,第一个元素的头结点和尾节点都为空,当第二个元素存储时,第一个元素的last节点指向第二个元素,first节点为null,第二个元素的first节点指向第一个元素,last节点指向null,以此类推。

原理图见下图

在这里插入图片描述

3.4.2.3 练习
public class LinkedListDemo {
    public static void main(String[] args) {
        List list = new LinkedList();
        list.add("张三");
        list.add("张三");
        list.add("李四");
        list.add("ABC");
        list.add("ABC");
        list.add(123456);// 当存入int类型数据时,集合会将int类型的数据自动装箱成Integer
        list.add(456);
        list.add(456);
        list.add(new Date());
        System.out.println(list);
        System.out.println("******************************");
        list.get(0);
        list.get(1);
        System.out.println("******************************");
        list.remove("张三");//删除排序靠前字符“张三”(有重复度的前提下),还可以通过索引删除,例如list.remove(2);
        System.out.println(list);
        System.out.println("******************************");
        System.out.println(list.size());
        System.out.println(list.contains(456));
        System.out.println("******************************");

        //迭代器遍历
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            Object next = iterator.next();
            System.out.println(next);
        }


    }
}


结果如下

在这里插入图片描述

3.4.1 Vector类

​ (1)Vector 是一个古老的集合, JDK1.0就有了。大多数操作与ArrayList相同,区别之处在于Vector是线程安全的。

​ (2)在各种list中,最好把ArrayList作为缺省选择。当插入、删除频繁时,使用LinkedList; Vector总是比ArrayList慢,所以尽量避免使用。

3.5 Set接口

Set接口继承自Collection,Set接口的实现类存储的数据不可以重复,它的实现类主要有三个,分别为HashSet类、LinkedHashSet类、TreeSet类。

3.5.1 Set接口特点

​ (1)无序,存储的数据没有索引,存储和取出的顺序不一样,但取出的顺序不会变。

​ (2)不允许有重复的数据,所以最多包含一个null。

3.5.2 HashSet类

​ HashSet 是 Set 接口的典型实现,大多数时候使用 Set 集合时都使用这个实现类。HashSet 按 Hash 算法来存储集合中的元素,因此具有很好的存取、查找、删除性能。

3.5.2.1 HashSet 的特点

(1)HashSet实现了Set接口。

(2)HashSet不是线程安全的。

(3)可以存放null值,但是只能有一个null。

(4)HashSet底层是HashMap实现的,只有key,value存储一个静态的new Object。

3.5.2.2 HashSet原理

在这里插入图片描述

3.5.2.3 练习
    public static void main(String[] args) {
        Set set = new HashSet();

        User u1 = new User("张三",18);
        User u2 = new User("李四",20);
        User u3 = new User("王五",25);
        User u4 = new User("张三",18);
        User u5 = new User("李四",20);
        User u6 = new User("王五",25);

        set.add(u1);
        set.add(u2);
        set.add(u3);
        set.add(u4);
        set.add(u5);
        set.add(u6);

        for(Object o : set){
            System.out.println(o);
        }
    }

结果

在这里插入图片描述

3.5.3 LinkedHashSet类

LinkedHashSet 是 HashSet 的子类。

3.5.3.1 LinkedHashSet特点

​ (1)LinkedHashSet 根据元素的 hashCode 值来决定元素的存储位置,但它同时使用双向链表维护元素的次序,这使得元素看起来是以插入顺序保存的。

​ (2)LinkedHashSet插入性能略低于 HashSet, 但在迭代访问 Set 里的全部元素时有很好的性能。

​ (3)LinkedHashSet 不允许集合元素重复。

3.5.3.2 LinkedSet底层结构

在这里插入图片描述

3.5.3.3 练习
public class LinkedSetDemo {

    public static void main(String[] args) {
        Set set = new LinkedHashSet();

        set.add("zzz");
        set.add("xxx");
        set.add("zzz");
        set.add("ooo");
        set.add("hhh");
        set.add("666");
        set.add("555");
        set.add("333");
        set.add("111");
        set.add("222");

        for (Object o : set) {
            System.out.println(o);
        }

    }
}

结果

在这里插入图片描述

3.5.4 TreeSet类

​ TreeSet 是 SortedSet 接口的实现类, TreeSet 可以确保集合元素处于排序状态。

3.5.4.1 TreeSet特点

​ (1)采用二叉树存储元素

​ (2)二叉树定义:每个节点最多两个节点的二叉树。

3.5.4.2 TreeSet存储原理

​ 第一次值,存储在顶端,

​ 第二次值,跟第一次值比较,小存左,大存右边。

​ 第三次值,跟第一次值比较,小存左,大存右边,接着跟第二次值比较。

​ (有重复的元素,会将重复的元素去掉)

​ 以此类推。

原理图见下图

在这里插入图片描述

3.5.4.3 练习
public class TreeSetDemo {

    public static void main(String[] args) {
        TreeSet set = new TreeSet();

        Student s1 = new Student("zhangsan",18);
        Student s2 = new Student("lisi",20);
        Student s3 = new Student("lisi",20);
        Student s4 = new Student("wangwu",14);
        Student s5 = new Student("wangwu",15);
        Student s6 = new Student("zhangsan",18);
        Student s7 = new Student("zhouliu",13);
        Student s8 = new Student("zhengqi",10);

        set.add(s1);
        set.add(s2);
        set.add(s3);
        set.add(s4);
        set.add(s5);
        set.add(s6);
        set.add(s7);
        set.add(s8);

        for (Object o : set) {
            System.out.println(o);
        }

    }
}

结果
在这里插入图片描述

4 Map接口

Map接口的实现类是双列集合,存放K-Y,key和value具有一一对应关系。

​ Map 集合是以 Key-Value 键值对作为存储元素实现的晗希结构, Key 按某种晗希函数计算后是唯一 的, Value 则是可以重复的。 Map 类提供三种 Collection 视图,在集合框架图中, Map 指向 Collection 的箭头仅表示两个类之间的依赖关系 。 可以使用keySet()查看所有的 K町,使用 values()查看所有的 Value ,使用 ent可Set()查看所有的键值对。最早用于存储键值对的 Hashtable 因为性能瓶颈已经被淘汰,而如今广泛使用的 HashMap , 线程是不安全的。 ConcurrentHashMap 是线程安全的,在 JDK8 中进行了锁的大幅度优化,体现出不错的性能。在多线程并发场景中,优先推荐使用ConcurrentHashMap ,而不是 HashMap 。 TreeMap 是 Key 有序的 Map 类集合。

4.1 Map特点
  1. 键的唯一性:Map中的键是唯一的,不允许重复。每个键只能对应一个值。
  2. 无序性:Map中的键值对是无序的,即不保证按照插入顺序或者其他规则进行存储和访问。
  3. 可以包含空键和空值:Map允许使用null作为键和值。但需要注意的是,某些Map的实现类如TreeMap不允许null键,而ConcurrentHashMap不允许null键和null值。
  4. 动态增长:Map的大小是可变的,在需要时可以动态地添加和删除键值对。
  5. 高效的查找操作:通过键来查找值的操作效率很高,不受Map中元素数量的影响。
  6. 不允许重复的键:当向Map中添加一个已存在的键时,会替换掉该键对应的值。
  7. 提供多种实现类:Java提供了多个实现了Map接口的类,如HashMap、TreeMap、LinkedHashMap等。每个实现类都有其自身的特点和适用场景。
4.2 主要方法
  1. put(key, value):将指定的键值对添加到Map中,如果该键已经存在,则会替换对应的值。
  2. get(key):根据指定的键获取对应的值。
  3. containsKey(key):检查Map中是否包含指定的键。
  4. containsValue(value):检查Map中是否包含指定的值。
  5. remove(key):根据指定的键删除对应的键值对。
  6. size():返回Map中键值对的数量。
  7. isEmpty():检查Map是否为空,即是否没有键值对。
  8. keySet():返回一个包含所有键的Set集合。
  9. values():返回一个包含所有值的Collection集合。
  10. entrySet():返回一个包含所有键值对(Entry)的Set集合。
  11. clear():清空Map,删除所有的键值对。
4.3 自然排序器和定制排序器

在Java中,Map接口的自然选择器和定制选择器是指用于对Map的键进行排序的方式。

4.3.1 自然排序器

​ 自然选择器(Natural Ordering): 自然选择器是指使用键的自然顺序进行排序。对于实现了Comparable接口的键类型,可以使用自然选择器进行排序。比如,对于String类型的键,自然选择器将按照字典顺序进行排序。

​ 使用自然选择器进行排序的示例代码:

javaCopy CodeMap<String, Integer> map = new TreeMap<>();  // TreeMap是基于红黑树实现的有序Map
map.put("apple", 2);
map.put("orange", 3);
map.put("banana", 1);

for (Map.Entry<String, Integer> entry : map.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

​ 输出结果会按照键的自然顺序进行排序:

Copy Codeapple: 2
banana: 1
orange: 3
4.3.2 定制排序器

​ 定制选择器(Custom Ordering): 定制选择器是指使用自定义的比较器(Comparator)来排序Map的键。通过Comparator可以指定按照某种特定的顺序对键进行排序,而不依赖于键的自然顺序。

​ 使用定制选择器进行排序的示例代码:

javaCopy CodeMap<String, Integer> map = new TreeMap<>(new Comparator<String>() {
    public int compare(String key1, String key2) {
        // 按照键的长度进行降序排序
        return Integer.compare(key2.length(), key1.length());
    }
});

map.put("apple", 2);
map.put("orange", 3);
map.put("banana", 1);

for (Map.Entry<String, Integer> entry : map.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}

​ 输出结果会按照键的长度进行降序排序:

Copy Codeorange: 3
apple: 2
banana: 1

通过自然选择器和定制选择器,我们可以实现对Map的键进行排序,以满足不同的需求。使用TreeMap作为有序的Map实现类,可以方便地应用自然选择器或定制选择器来排序键。

4.4 HashMap类

​ HashMap是Map接口的实现类

4.4.1 HashMap原理
  1. 存储结构:HashMap由一个数组(Entry数组)和若干个链表(或红黑树)组成。数组中的每个元素称为一个桶(Bucket),每个桶存储着一个Entry对象。如果多个Entry的哈希码相同,它们就会放入同一个桶中,形成一个链表(或红黑树)。
  2. 哈希函数计算:当我们向HashMap中插入一个键值对时,首先会调用键的hashCode()方法得到一个哈希码。哈希码是通过哈希函数将键映射为一个整数。
  3. 确定存储位置:根据哈希码和数组的长度,使用取模运算确定键值对在数组中的存储位置,即桶的索引值。
  4. 添加键值对:如果该桶为空,直接将键值对作为新的Entry对象存储在桶中。如果该桶非空,会进行以下操作:
    • 遍历链表(或红黑树)中的每个Entry对象,检查键是否已经存在。如果存在,更新对应的值。
    • 如果不存在重复的键,将新的键值对添加到链表的末尾(或红黑树中)。
  5. 链表转化为红黑树:当某个桶中的链表长度达到一定阈值(默认为8),并且数组大小大于64时,会将该链表转化为红黑树,以提高查找效率。
  6. 扩容与重新哈希:当HashMap中键值对的数量超过负载因子(默认为0.75)与数组长度的乘积时,会自动进行扩容操作。扩容会创建一个新的更大的数组,并重新计算每个键值对在新数组中的位置,这个过程称为重新哈希。
  7. 查找键值对:当我们通过键来获取值时,首先根据键的哈希码和数组长度找到对应的桶,然后遍历链表(或红黑树)中的每个Entry对象,找到匹配的键值对。
4.4.2 练习
 public void test1(){
        Map map = new HashMap();
        Employee e1 = new Employee("小明",1001,19000.58);
        Employee e2 = new Employee("小伟",1002,1200000.80);
        Employee e3 = new Employee("小丽",1003,8000.25);



        map.put(1001,e1);
        map.put(1002,e2);
        map.put(1003,e3);


            System.out.println(map.keySet());

            for (Object o : map.keySet()) {
                Employee a = (Employee) map.get(o);
                if(a.getWages() > 18000){
                    System.out.println(a);
                }

            }
            System.out.println("------------");

            Set key = map.keySet();
            Iterator iterator = map.keySet().iterator();
            while (iterator.hasNext()) {
                Object a = iterator.next();
                Employee next =(Employee) map.get(a);
                if(next.getWages() > 18000) {
                    System.out.println(next);
                }

            }

            System.out.println("------------");

            Set entries = map.entrySet();
            Iterator it = entries.iterator();
            while (it.hasNext()) {
                Map.Entry entry = (Map.Entry)it.next();

                System.out.println(entry.getKey() + "--" + entry.getValue());

            }
        }
    

结果

在这里插入图片描述

4.5 LinkedHashMap

​ (1)LinkedHashSet和LinedHashMap的关系,从逻辑上这两个集合实现方式完全一致,只是LinkedHashSet使用LinkedHashMap实现,只有key,而value是一个静态的空对象

​ (2)底层使用链表实现

​ (3)有顺序(插入顺序),没有重复的集合

4.5.1 练习
4.6 TreeMap

​ TreeMap是基于红黑树实现的有序映射(SortedMap)接口的实现类.

4.6 .1 TreeMap特点
  1. 有序性:TreeMap中的键值对是有序的,默认按照键的自然顺序或者通过Comparator进行排序。这使得TreeMap在需要按照键的顺序进行遍历、范围查找等操作时非常有用。
  2. 键的唯一性:TreeMap中的键是唯一的,不允许重复。如果尝试将重复的键添加到TreeMap中,新的值会替换旧的值。
  3. 允许使用null键(但不建议):TreeMap允许使用null作为键,但需要注意,如果使用null作为键,需要保证在比较器(Comparator)中能正确处理null的情况,否则可能会导致NullPointerException。
  4. 底层数据结构:TreeMap使用红黑树(Red-Black Tree)作为底层的存储结构,以实现有序性和高效的插入、删除和查找操作。红黑树是一种自平衡的二叉搜索树,它保持着良好的平衡性,可以在O(log n)的时间内进行这些操作。
  5. 高效的插入、删除和查找操作:由于红黑树的平衡特性,TreeMap中插入、删除和查找操作的时间复杂度为O(log n)。
  6. 不是线程安全的:TreeMap是非线程安全的,不适合在多线程环境下使用。如果需要在多个线程中使用TreeMap,可以考虑使用ConcurrentSkipListMap。
  7. 支持导航方法:TreeMap提供了一些导航方法,如firstKey()、lastKey()、lowerKey()、higherKey()等,用于获取最小键、最大键和比给定键小或大的键。
4.6.2 练习
public class MapDemo {

    public static void main(String[] args) {
        User u1 = new User("aaa", 15);
        User u2 = new User("ggg", 17);
        User u3 = new User("ccc", 19);
        User u4 = new User("ddd", 30);
        User u5 = new User("fff", 48);
        User u6 = new User("zzz", 78);

        User u7 = new User("aaa", 16);
        User u8 = new User("ggg", 18);
        User u9 = new User("vvv", 25);
        User u10 = new User("ddd", 30);
        User u11 = new User("fff", 48);
        User u12 = new User("zzz", 78);

        Comparator com = new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                if (o1 instanceof User && o2 instanceof User) {
                    User u1 = (User) o1;
                    User u2 = (User) o2;

                    return Integer.compare(u1.getAge(), u2.getAge());
                } else {
                    throw new RuntimeException("输入的类型不匹配");
                }

            }
        };

        Map map = new TreeMap(com);
        map.put(u1,1);
        map.put(u2,2);
        map.put(u3,3);
        map.put(u4,4);
        map.put(u5,5);
        map.put(u6,6);
        map.put(u7,7);
        map.put(u8,8);
        map.put(u9,9);
        map.put(u10,10);
        map.put(u11,11);
        map.put(u12,12);

        System.out.println(map);

        System.out.println("********************");
        Set key = map.keySet();
        for (Object o : key) {
            System.out.println(o);
        }


    }
}

结果

在这里插入图片描述

4.7 Hashtable

​ (1)Hashtable是个古老的 Map 实现类, JDK1.0就提供了。不同于HashMap,Hashtable是线程安全的。

​ (2)Hashtable实现原理和HashMap相同,功能相同。底层都使用哈希表结构,查询速度快,很多情况下可以互用。

​ (3)与HashMap不同, Hashtable 不允许使用 null 作为 key 和 value

​ (4)与HashMap一样, Hashtable 也不能保证其中 Key-Value 对的顺序

​ (5)Hashtable判断两个key相等、两个value相等的标准, 与HashMap一致。

4.8 Properties

(1)Properties 类是 Hashtable 的子类,该对象用于处理属性文件

(2)由于属性文件里的 key、 value 都是字符串类型,所以 Properties 里的 key和 value 都是字符串类型

(3)存取数据时,建议使用setProperty(String key,String value)方法和getProperty(String key)方法

5 Collections工具类

​ 在Java中,Collections工具类提供了一系列静态方法,用于对集合类(Collection)进行常见的操作,例如排序、查找、替换等。以下是一些常用的Collections工具类方法:

  1. 排序操作:
  • sort(List list)`: 对List进行自然排序,要求元素类型实现Comparable接口。
  • sort(List<T> list, Comparator<? super T> c): 对List进行指定比较器的排序。
  • reverse(List<?> list): 反转List中元素的顺序。

2.查找和替换:

  • binarySearch(List<? extends Comparable<? super T>> list, T key): 使用二分查找算法在已排序的List中搜索指定的键,并返回找到的元素索引;如果找不到,则返回负数。
  • binarySearch(List<? extends T> list, T key, Comparator<? super T> c): 使用指定比较器在已排序的List中搜索指定的键,并返回找到的元素索引;如果找不到,则返回负数。
  • replaceAll(List<T> list, T oldVal, T newVal): 将List中所有等于旧值的元素都替换为新值。
  • frequency(Collection<?> c, Object o): 返回Collection中与指定对象相等的元素的个数。

3.同步控制:

  • synchronizedCollection(Collection<T> c): 返回一个线程安全的Collection,其中所有访问方法都需要进行同步处理。
  • synchronizedList(List<T> list): 返回一个线程安全的List,其中所有访问方法都需要进行同步处理。
  • synchronizedSet(Set<T> s): 返回一个线程安全的Set,其中所有访问方法都需要进行同步处理。

4.不可修改集合:

  • unmodifiableCollection(Collection<? extends T> c): 返回一个不能修改的Collection,任何修改操作都会抛出UnsupportedOperationException异常。
  • unmodifiableList(List<? extends T> list): 返回一个不能修改的List,任何修改操作都会抛出UnsupportedOperationException异常。
  • unmodifiableSet(Set<? extends T> s): 返回一个不能修改的Set,任何修改操作都会抛出UnsupportedOperationException异常。

5…

5.1 练习
public class CollectionsDemo {

    public static void main(String[] args) {
        List list =new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("zzz");
        list.add("ggg");
        list.add("eee");
        list.add("555");
        list.add("444");
        list.add("999");
        list.add("333");
        list.add("111");

        System.out.println(list);

        Collections.reverse(list);
        System.out.println(list);

        Collections.shuffle(list);
        System.out.println(list);

        Collections.sort(list);
        System.out.println(list);


        Comparator com = new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                String s1 = (String) o1;
                String s2 = (String) o2;
                return s1.compareTo(s2);
            }
        };

        Collections.sort(list,com);
        System.out.println(list);

        Collections.swap(list,0,1);
        System.out.println(list);

        System.out.println(Collections.max(list));

        System.out.println(Collections.frequency(list,"aaa"));

        List syncList = Collections.synchronizedList(list);
        syncList.add("666");
        System.out.println(list);
    }
}

结果

在这里插入图片描述

6 结束语

学习是个枯燥而又漫长的过程,且这个过程没有终点。

​ 有时候我真的想快点学,但是,哪怕是一个知识点,从零开始学都可能花费半个小时甚至一个小时才能学会,而且你还不一定掌握住,可能换个思路,换个问题,这个知识点你又不会了。

​ 学一个知识点还不是最难得,最难得将你学的知识点进行串联,融会贯通,举一反三。

但是我相信,量变终会变成质变。

加油吧,少年。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值