集合

集合


集合类简介

Java 集合就像一种容器,可以把多个对象(实际上是对象的引用,但习惯上都称对象)“丢进”该容器中。从 Java 5 增加了泛型以后,Java 集合可以记住容器中对象的数据类型,使得编码更加简洁、健壮。

Java 集合大致可以分为两大体系,一个是 Collection,另一个是 Map;

  • Collection :主要由List、Set、Queue接口组成,List代表有序、重复的集合;其中Set代表无序、不可重复的集合;Java 5 又增加了Queue体系集合,代表一种队列集合实现。
  • Map:则代表具有映射关系的键值对集合。

Collection接口结构

img

Map接口结构

img

黄色块为集合的接口,蓝色块为集合的实现类。

和数组的区别:

  • 1:长度的区别

    • 数组的长度固定
    • 集合的长度可变
  • 2:元素的数据类型

    • 数组可以存储基本数据类型,也可以存储引用类型
    • 集合只能存储引用类型(你存储的是简单的int,它会自动装箱成Integer)
  • 位置: java.util.*;

Java集合接口的作用

接口名称 作 用
Iterator接口 集合的输出接口,主要用于遍历输出(即迭代访问)Collection 集合中的元素,Iterator 对象被称之为迭代器。迭代器接口是集合接口的父接口,实现类实现 Collection 时就必须实现 Iterator 接口。
Listlterator Iterator 子接口,ListIterator针对 List 特化的迭代器,可以双向输出集合中的元素。
Collection接口 是 List、Set 和 Queue 的父接口,是存放一组单值的最大接口。所谓的单值是指集合中的每个元素都是一个对象。一般很少直接使用此接口直接操作。
List 接口 是最常用的接口。是有序集合,允许有相同的元素。使用 List 能够精确地控制每个元素插入的位置,用户能够使用索引(元素在 List 中的位置,类似于数组下标)来访问 List 中的元素,与数组类似。
Set 接口 不能包含重复的元素。
Map 接口 是存放一对值的最大接口,即接口中的每个元素都是一对,以 key➡value 的形式保存。
Queue 接口 Queue 是 Java 提供的队列实现,有点类似于 List。
Dueue 接口 是 Queue 的一个子接口,为双向队列。
Enumeration 传统的输出接口,已经被Iterator 取代
SortedSet Set 的子接口,可以对集合中的元索进行排序。
SortedMap Map的子接口,可以对集合中的元素进行排序。
Map.Entry Map的内部接口,描述Map中存储的- -组键值对元素

对于 Set、List、Queue 和 Map 这 4 种集合,Java 最常用的实现类分别是 HashSet、TreeSet、ArrayList、ArrayDueue、LinkedList 和 HashMap、TreeMap 等。

Collection体系集合

Collection的由来:

  • 集合可以存储多个元素,但我们对多个元素也有不同的需求

    • 多个元素,不能有相同的
    • 多个元素,能够按照某个规则排序
  • 针对不同的需求:java就提供了很多集合类,多个集合类的数据结构不同。但是,结构不重要,重要的是能够存储东西,能够判断,获取

  • 把集合共性的内容不断往上提取,最终形成集合的继承体系---->Collection

    collection

img


Collection父接口

Collection 接口是 List、Set 和 Queue 接口的父接口,通常情况下不被直接使用。Collection 接口定义了一些通用的方法,通过这些方法可以实现对集合的基本操作。定义的方法既可用于操作 Set 集合,也可用于操作 List 和 Queue 集合。

  • Collection接口的常用方法:
方法名称 说明
boolean add(E e) 向集合中添加一个元素,如果集合对象被添加操作改变了,则返回 true。E 是元素的数据类型
boolean addAll(Collection c) 向集合中添加集合 c 中的所有元素,如果集合对象被添加操作改变了,则返回 true。
void clear() 清除集合中的所有元素,将集合长度变为 0。
boolean remove(Object o) 从集合中删除一个指定元素,当集合中包含了一个或多个元素 o 时,该方法只删除第一个符合条件的元素,该方法将返回 true。
boolean removeAll(Collection c) 从集合中删除所有在集合 c 中出现的元素(相当于把调用该方法的集合减去集合 c)。如果该操作改变了调用该方法的集合,则该方法返回 true。
boolean contains(Object o) 判断集合中是否存在指定元素
boolean containsAll(Collection c) 判断集合中是否包含集合 c 中的所有元素
boolean isEmpty() 判断集合是否为空
Iteratoriterator() 返回一个 Iterator 对象,用于遍历集合中的元素
int size() 返回集合中元素的个数
boolean retainAll(Collection c) 从集合中删除集合 c 里不包含的元素(相当于把调用该方法的集合变成该集合和集合 c 的交集),如果该操作改变了调用该方法的集合,则该方法返回 true。
T[] toArray(T[] a) 将指定集合转变成对应的数组
Object[] toArray() 把集合转换为一个数组,所有的集合元素变成对应的数组元素。
int hashCode() 返回此集合的哈希码值。

img

迭代器(Iterator)介绍

我们可以发现Collection的源码中继承了Iterable,有iterator()这个方法...,所以,Collection是Iterable接口的子接口

img

Iterable是一个接口:

img

它有iterator()这个方法,返回的是Iterator再来看一下,Iterator也是一个接口,它只有三个方法:

  • boolean hasNext() 判断集合中是否有元素,如果有元素可以迭代,就返回true。(当调用hasNext方法的时候,只是判断下一个元素的有无,并不移动指针)
  • E next() 返回迭代的下一个元素,注意: 如果没有下一个元素时,调用next元素会抛出NoSuchElementException
  • void remove()从迭代器指向的集合中移除迭代器返回的最后一个元素(可选操作)。

img

可是,我们没能找到对应的实现方法,只能往Collection的子类下找找了,于是我们找到了--->ArrayList,于是,我们在ArrayList下找到了iterator实现的身影:它是在ArrayList以内部类的方式实现的!并且,从源码可知:Iterator实际上就是在遍历集合

img

所以说:我们遍历集合(Collection)的元素都可以使用Iterator,至于它的具体实现是以内部类的方式实现的!

2021 03 26 13 34 14rkQ6s9

迭代器的遍历

第一种方式:while循环

public static void main(String[] args) {
		ArrayList list = new ArrayList();
		// 增加:add() 将指定对象存储到容器中
		list.add("计算机网络");
		list.add("现代操作系统");
		list.add("java编程思想");
		list.add("java核心技术");
		list.add("java语言程序设计");
		System.out.println(list);
		Iterator it = list.iterator();
		while (it.hasNext()) {
			String next = (String) it.next();
			System.out.println(next);
		}
	}

第二种方式:for循环

public class Demo2 {
	public static void main(String[] args) {
		ArrayList list = new ArrayList();
		// 增加:add() 将指定对象存储到容器中
		list.add("计算机网络");
		list.add("现代操作系统");
		list.add("java编程思想");
		list.add("java核心技术");
		list.add("java语言程序设计");
		System.out.println(list);
    
 		Iterator it = list.iterator()
		for (;it.hasNext();) {
       //迭代器的next方法返回值类型是Object,所以要记得类型转换。
			String next = (String) it.next();
			System.out.println(next);
		}
	}
}

需要取出所有元素时,可以通过循环,java 建议使用for 循环。因为可以对内存进行一下优化。

第三种方式:使用迭代器清空集合

public class Demo1 {
	public static void main(String[] args) {
		Collection coll = new ArrayList();
		coll.add("aaa");
		coll.add("bbb");
		coll.add("ccc");
		coll.add("ddd");
		System.out.println(coll);
		Iterator it = coll.iterator();
		while (it.hasNext()) {
			it.next();
			it.remove();
		}
		System.out.println(coll);
	}
}

需要注意的细节如下:

细节一:

如果迭代器的指针已经指向了集合的末尾,那么如果再调用next()会返回NoSuchElementException异常

public class Demo2 {
	public static void main(String[] args) {
		ArrayList list = new ArrayList();
		// 增加:add() 将指定对象存储到容器中
		list.add("计算机网络");
		list.add("现代操作系统");
		list.add("java编程思想");
		list.add("java核心技术");
		list.add("java语言程序设计");
		System.out.println(list);
 
		Iterator it = list.iterator();
		while (it.hasNext()) {
			String next = (String) it.next();
			System.out.println(next);
		}
		// 迭代器的指针已经指向了集合的末尾
		// String next = (String) it.next();
		// java.util.NoSuchElementException
	}
}

细节二:

如果调用remove之前没有调用next是不合法的,会抛出IllegalStateException

public class Demo2 {
	public static void main(String[] args) {
		ArrayList list = new ArrayList();
		// 增加:add() 将指定对象存储到容器中
		list.add("计算机网络");
		list.add("现代操作系统");
		list.add("java编程思想");
		list.add("java核心技术");
		list.add("java语言程序设计");
		System.out.println(list);
 
		Iterator it = list.iterator();
		while (it.hasNext()) {
			// 调用remove之前没有调用next是不合法的
			// it.remove();
			// java.lang.IllegalStateException
			String next = (String) it.next();
			System.out.println(next);
		} 
	}
}

细节三:

重复使用next()的未知错误(先学习Map再看这个例子)。

        TreeMap treemap = new TreeMap();

        treemap.put(1, "Hello");
        treemap.put(3, ",");
        treemap.put(6, "java");
        treemap.put(4, "hello");
        treemap.put(2, "world");
        treemap.put(5, "___");

        Set key = treemap.keySet();
        Iterator iterator = key.iterator();
        while (iterator.hasNext()) {
            System.out.println(
                    iterator.next() + "~~~~" +
                            treemap.get(iterator.next())
            );
        }

运行结果:

image-20210326140545984

原因:每次next()指针都移向下一个元素

iShot2021-03-26 14.25.01

while内改为:

int i= (int) iterator.next();
System.out.println(i+ "~~~~" +treemap.get(i));

List集合介绍

List 是一个有序、可重复的集合,集合中每个元素都有其对应的顺序索引。List 集合允许使用重复元素,可以通过索引来访问指定位置的集合元素。List 集合默认按元素的添加顺序设置元素的索引,第一个添加到 List 集合中的元素的索引为 0,第二个为 1,依此类推。

我们来看一下List接口的方法,比Collection多了一点点:

  • List集合的特点就是:有序(存储顺序和取出顺序一致),可重复

img

Collection返回的是Iterator迭代器接口,而List中又有它自己对应的实现-->ListIterator接口

该接口比普通的Iterator接口多了几个方法: img

从方法名就可以知道:ListIterator可以往前遍历,添加元素,设置元素

List 接口

List 常用的扩展方法

方法名称 说明
E get(int index) 获取此集合中指定索引位置的元素,E 为集合中元素的数据类型
int index(Object o) 返回此集合中第一次出现指定元素的索引,如果此集合不包含该元 素,则返回 -1
int lastIndexOf(Object o) 返回此集合中最后一次出现指定元素的索引,如果此集合不包含该 元素,则返回 -1
E set(int index, Eelement) 将此集合中指定索引位置的元素修改为 element 参数指定的对象。 此方法返回此集合中指定索引位置的原元素
List subList(int fromlndex, int tolndex) 返回一个新的集合,新集合中包含 fromlndex 和 tolndex 索引之间 的所有元素。包含 fromlndex 处的元素,不包含 tolndex 索引处的 元素
ListIteratorlistIterator() 实例化 ListIterator 接口,用来遍历 List 集合

注意:当调用 List 的 set(int index, Object element) 方法来改变 List 集合指定索引处的元素时,指定的索引必须是 List 集合的有效索引。例如集合长度为 4,就不能指定替换索引为 4 处的元素,也就是说这个方法不会改变 List 集合的长度。

List集合常用子类(实现类)

List集合常用的子类有三个:

  • ArrayList

    • 底层数据结构是数组,查询快,增删慢,线程不安全,效率高,可以存储重复元素。
  • LinkedList

    • 底层数据结构是链表,查询慢,增删快,线程不安全,效率高,可以存储重复元素。
    • LinkedList 类除了包含 Collection 接口和 List 接口中的所有方法之外,还特别提供了如下所示的方法。
    方法名称 说明
    void addFirst(E e) 将指定元素添加到此集合的开头
    void addLast(E e) 将指定元素添加到此集合的末尾
    E getFirst() 返回此集合的第一个元素
    E getLast() 返回此集合的最后一个元素
    E removeFirst() 删除此集合中的第一个元素
    E removeLast() 删除此集合中的最后一个元素
  • Vector

    • 底层数据结构是数组,查询快,增删慢,线程安全,效率低,可以存储重复元素。
    • 每个方法使用synchronized修饰,上锁
  • Stack
    栈(Stack)是常见的数据结构之一,继承了 Vector,它的特性是 后进先出(LIFO),提供了常用的方法:

    push(x):将 x 入栈;

    pop():弹出栈顶元素;

    peek():获取栈顶元素;

    isEmpty():判断栈是否为空,空返回 true,否则返回 false;

小结

img

Set集合

跟 List 一样,Set 是 Collection 的子接口,Set 集合是以散列的形式存储数据,所以元素是没有顺序的,可以存储一组无序且唯一的数据。

Set 集合类似于一个罐子,程序可以依次把多个对象“丢进”Set 集合,而 Set 集合通常不能记住元素的添加顺序。也就是说 Set 集合中的对象不按特定的方式排序,只是简单地把对象加入集合。Set 集合中不能包含重复的对象,并且最多只允许包含一个 null 元素。

Set 常用实现类:

  • HashSet
  • LinkedHashSet
  • TreeSet

HashSet

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

HashSet 具有以下特点:

  • 不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也有可能发生变化。
  • HashSet 不是同步的,如果多个线程同时访问或修改一个 HashSet,则必须通过代码来保证其同步。
  • 集合元素值可以是 null。

HashSet 底层由哈希表支持,具有非常好性能,它的工作原理是这样的:当向 HashSet 中插入数据的时候,他会调用对象的 hashCode() 得到该对象的哈希码,然后根据哈希码计算出该对象插入到集合中的位置。实际上 HashSet 相当于 HashMap 的 key 部分,允许 null 元素:

在 HashSet 类中实现了 Collection 接口中的所有方法。HashSet 类的常用构造方法重载形式如下。

  • HashSet():构造一个新的空的 Set 集合。
  • HashSet(Collection<? extends E>c):构造一个包含指定 Collection 集合元素的新 Set 集合。其中,“< >”中的 extends 表示 HashSet 的父类,即指明该 Set 集合中存放的集合元素类型。c 表示其中的元素将被存放在此 Set 集合中。

LinkedHashSet和HashSet对比

类型 底层依赖 底层实现 是否有序 顺序遍历性能 插入性能 随机访问性能
HashSet HashSet->HashMap 数组+链表+红黑树 几乎一致
LinkedHashSet LinkedHashSet->LinkedHashMap->HashMap 数组+双向链表+红黑树 插入顺序 几乎一致

HashSet&LinkedHashSet 如何判断两个对象是否相等?

首先会判断两个对象的 hashCode 是否相等

什么是 hashCode?

将对象的内部信息(内存地址、属性值等),通过某种特定规则转换成一个散列值,就是该对象的 hashCode。

  • 两个不同对象的hashCode值可能相等
  • hashCode不相等的两个对象一定不是同一个对象

引用类型具体的对象(属性)存储在堆中的,再将堆中对象的内存地址赋值给栈中的变量 data,data 中存储的就是地址。

基本数据类型不需要用到堆内存,变量在栈中,变量的值直接存储在变量中。

集合在判断两个对象是否相等的时候,会先比较他们的 hashCode,如果 hashCode 不相等,则认为不是同一个对象,可以添加。

如果 hashCode 值相等,还不能认为两个对象是相等的,需要通过 equals 进行进一步的判断,equals 相等,则两个对象相等,否则两个对象不相等。

强调:向 HashSet 或 HashMap 中加入数据时必须同时覆盖 equals() 和 hashCode() 方法,通过这两个方法保证元素的唯一性。如果 hashCode 值相同,才会判断 equals 是否为true。如果 hashCode 值不同,不会调用equals。

TreeSet

TreeSet 类同时实现了 Set 接口和 SortedSet 接口。SortedSet 接口是 Set 接口的子接口,可以实现对集合进行自然排序,因此使用 TreeSet 类实现的 Set 接口默认情况下是自然排序的,这里的自然排序指的是升序排序。

TreeSet 底层是二叉树,可以对 Set 集合进行排序, 默认自然排序(即升序)。或者根据在创建时提供的 Comparator 进行排序。

TreeSet 只能对实现了 Comparable 接口的类对象进行排序,因为 Comparable 接口中有一个 compareTo(Object o) 方法用于比较两个对象的大小。例如 a.compareTo(b),如果 a 和 b 相等,则该方法返回 0;如果 a 大于 b,则该方法返回大于 0 的值;如果 a 小于 b,则该方法返回小于 0 的值。
TreeSet 类除了实现 Collection 接口的所有方法之外,还提供了如表所示的方法。

方法名称 说明
E first() 返回此集合中的第一个元素。其中,E 表示集合中元素的数据类型
E last() 返回此集合中的最后一个元素
E poolFirst() 获取并移除此集合中的第一个元素
E poolLast() 获取并移除此集合中的最后一个元素
SortedSet subSet(E fromElement,E toElement) 返回一个新的集合,新集合包含原集合中 fromElement 对象与 toElement 对象之间的所有对象。包含 fromElement 对象,不包含 toElement 对象
SortedSet headSet<E toElement〉 返回一个新的集合,新集合包含原集合中 toElement 对象之前的所有对象。 不包含 toElement 对象
SortedSet tailSet(E fromElement) 返回一个新的集合,新集合包含原集合中 fromElement 对象之后的所有对 象。包含 fromElement 对象

注意:表面上看起来这些方法很多,其实很简单。因为 TreeSet 中的元素是有序的,所以增加了访问第一个、前一个、后一个、最后一个元素的方法,并提供了 3 个从 TreeSet 中截取子 TreeSet 的方法。

注意⚠️:使用TreeSet要注意对存储的对象实现Comparable接口的compareTo(Object o) 方法

Map体系

Map 是一种键-值对(key-value)集合,Map 集合中的每一个元素都包含一个键(key)对象和一个值(value)对象。用于保存具有映射关系的数据。

Map 集合里保存着两组值,一组值用于保存 Map 里的 key,另外一组值用于保存 Map 里的 value,key 和 value 都可以是任何引用类型的数据。Map 的 key 不允许重复,value 可以重复,即同一个 Map 对象的任何两个 key 通过 equals 方法比较总是返回 false。

Map 中的 key 和 value 之间存在单向一对一关系,即通过指定的 key,总能找到唯一的、确定的 value。从 Map 中取出数据时,只要给出指定的 key,就可以取出对应的 value。

Map 接口中提供的常用方法如表所示。

方法名称 说明
void clear() 删除该 Map 对象中的所有 key-value 对。
boolean containsKey(Object key) 查询 Map 中是否包含指定的 key,如果包含则返回 true。
boolean containsValue(Object value) 查询 Map 中是否包含一个或多个 value,如果包含则返回 true。
V get(Object key) 返回 Map 集合中指定键对象所对应的值。V 表示值的数据类型
V put(K key, V value) 向 Map 集合中添加键-值对,如果当前 Map 中已有一个与该 key 相等的 key-value 对,则新的 key-value 对会覆盖原来的 key-value 对。
void putAll(Map m) 将指定 Map 中的 key-value 对复制到本 Map 中。
V remove(Object key) 从 Map 集合中删除 key 对应的键-值对,返回 key 对应的 value,如果该 key 不存在,则返回 null
boolean remove(Object key, Object value) 这是 Java 8 新增的方法,删除指定 key、value 所对应的 key-value 对。如果从该 Map 中成功地删除该 key-value 对,该方法返回 true,否则返回 false。
Set entrySet() 返回 Map 集合中所有键-值对的 Set 集合,此 Set 集合中元素的数据类型为 Map.Entry
Set keySet() 返回 Map 集合中所有键对象的 Set 集合
boolean isEmpty() 查询该 Map 是否为空(即不包含任何 key-value 对),如果为空则返回 true。
int size() 返回该 Map 里 key-value 对的个数
Collection values() 返回该 Map 里所有 value 组成的 Collection

Map 集合最典型的用法就是成对地添加、删除 key-value 对,接下来即可判断该 Map 中是否包含指定 key,也可以通过 Map 提供的 keySet() 方法获取所有 key 组成的集合,进而遍历 Map 中所有的 key-value 对。下面程序示范了 Map 的基本功能。

为什么keySet()返回Set 集合,values()返回Collection集合

原因:key值唯一,value不唯一

注意:修改使用put方法

Map 接口的实现类

  • HashMap:存储一组无序,key 不可以重复,value 可以重复的元素。
  • Hashtable:存储一组无序,key 不可以重复,value 可以重复的元素。
  • TreeMap:存储一组有序,key 不可以重复,value 可以重复的元素,可以按照 key 进行排序。
  • 这里写图片描述

Hashtable 用法与 HashMap 基本一样,它们的区别是,Hashtable 是线程安全的,但是性能较低。HashMap 是非线程安全的,但是性能较高。

HashMap,方法没有用 synchronized 修饰,所以是非线程安全的。

Hashtable,方法用 synchronized 修饰,所以是线程安全的。

这里写图片描述

HashMap 和 Hashtable,保存的数据都是无序的,Map 的另外一个实现类 TreeMap 主要功能是按照 key 对集合中的元素进行排序。

⚠️重写 key对应类的compare接口的compareTo方法

遍历Map集合

Map 集合的遍历与 List 和 Set 集合不同。Map 有两组值,因此遍历时可以只遍历值的集合,也可以只遍历键的集合,也可以同时遍历。Map 以及实现 Map 的接口类(如 HashMap、TreeMap、LinkedHashMap、Hashtable 等)都可以用以下几种方式遍历。

1)在 for 循环中使用 entries 实现 Map 的遍历(最常见和最常用的)。

public static void main(String[] args) {
    Map<String, String> map = new HashMap<String, String>();
    map.put("邓超", "孙俪");
    map.put("李晨", "范冰冰);
    map.put("刘德华", "柳岩);
    for (Map.Entry<String, String> entry : map.entrySet()) {
        String mapKey = entry.getKey();
        String mapValue = entry.getValue();
        System.out.println(mapKey + ":" + mapValue);
    }

img

2)使用 for-each 循环遍历 key 或者 values,一般适用于只需要 Map 中的 key 或者 value 时使用。性能上比 entrySet 较好。

Map<String, String> map = new HashMap<String, String>();
map.put("Java入门教程", "http://c.biancheng.net/java/");
map.put("C语言入门教程", "http://c.biancheng.net/c/");
// 打印键集合
for (String key : map.keySet()) {
    System.out.println(key);
}
// 打印值集合
for (String value : map.values()) {
    System.out.println(value);
}

3)使用迭代器(Iterator)遍历

Map<String, String> map = new HashMap<String, String>();
map.put("Java入门教程", "http://c.biancheng.net/java/");
map.put("C语言入门教程", "http://c.biancheng.net/c/");
Iterator<Entry<String, String>> entries = map.entrySet().iterator();
while (entries.hasNext()) {
    Entry<String, String> entry = entries.next();
    String key = entry.getKey();
    String value = entry.getValue();
    System.out.println(key + ":" + value);
}

注意:Map集合不能直接使用迭代器或者foreach进行遍历。但是转成Set之后就可以使用了。

4)通过键找值遍历,这种方式的效率比较低,因为本身从键取值是耗时的操作。

for(String key : map.keySet()){
    String value = map.get(key);
    System.out.println(key+":"+value);
}

Collections工具类

Collections 类是 Java 提供的一个操作 Set、List 和 Map 等集合的工具类。Collections 类提供了许多操作集合的静态方法,借助这些静态方法可以实现集合元素的排序、查找替换和复制等操作。下面介绍 Collections 类中操作集合的常用方法。

排序(正向和逆向)

Collections 提供了如下方法用于对 List 集合元素进行排序。

  • void reverse(List list):对指定 List 集合元素进行逆向排序。
  • void shuffle(List list):对 List 集合元素进行随机排序(shuffle 方法模拟了“洗牌”动作)。
  • void sort(List list):根据元素的自然顺序对指定 List 集合的元素按升序进行排序。
  • void sort(List list, Comparator c):根据指定 Comparator 产生的顺序对 List 集合元素进行排序。
  • void swap(List list, int i, int j):将指定 List 集合中的 i 处元素和 j 处元素进行交换。
  • void rotate(List list, int distance):当 distance 为正数时,将 list 集合的后 distance 个元素“整体”移到前面;当 distance 为负数时,将 list 集合的前 distance 个元素“整体”移到后面。该方法不会改变集合的长度。

查找、替换操作

Collections 还提供了如下常用的用于查找、替换集合元素的方法。

  • int binarySearch(List list, Object key):使用二分搜索法搜索指定的 List 集合,以获得指定对象在 List 集合中的索引。如果要使该方法可以正常工作,则必须保证 List 中的元素已经处于有序状态。
  • Object max(Collection coll):根据元素的自然顺序,返回给定集合中的最大元素。
  • Object max(Collection coll, Comparator comp):根据 Comparator 指定的顺序,返回给定集合中的最大元素。
  • Object min(Collection coll):根据元素的自然顺序,返回给定集合中的最小元素。
  • Object min(Collection coll, Comparator comp):根据 Comparator 指定的顺序,返回给定集合中的最小元素。
  • void fill(List list, Object obj):使用指定元素 obj 替换指定 List 集合中的所有元素。
  • int frequency(Collection c, Object o):返回指定集合中指定元素的出现次数。
  • int indexOfSubList(List source, List target):返回子 List 对象在父 List 对象中第一次出现的位置索引;如果父 List 中没有出现这样的子 List,则返回 -1。
  • int lastIndexOfSubList(List source, List target):返回子 List 对象在父 List 对象中最后一次出现的位置索引;如果父 List 中没有岀现这样的子 List,则返回 -1。
  • boolean replaceAll(List list, Object oldVal, Object newVal):使用一个新值 newVal 替换 List 对象的所有旧值 oldVal。

复制

Collections 类的 copy() 静态方法用于将指定集合中的所有元素复制到另一个集合中。执行 copy() 方法后,目标集合中每个已复制元素的索引将等同于源集合中该元素的索引。

copy() 方法的语法格式如下:

void copy(List <? super T> dest,List<? extends T> src)

其中,dest 表示目标集合对象,src 表示源集合对象。

注意:目标集合的长度至少和源集合的长度相同,如果目标集合的长度更长,则不影响目标集合中的其余元素。如果目标集合长度不够而无法包含整个源集合元素,程序将抛出 IndexOutOfBoundsException 异常。

posted @ 2021-03-26 13:40  一头浓发的程序员  阅读(95)  评论(0)    收藏  举报