1. Java 集合框架(Java Collections Framework)
- 集合(Collection),存储元素的容器(即对象的容器)
- List集合(线性集合)
- Set集合(去重集合)
- Queue集合(队列集合)
- 图(Map),存储
K-V键值对
的容器
1.1 集合(java.util.Collection)
- java.util.List
- java.util.Set
- java.util.Queue
1.2 图(Map)
- java.util.Map
2. 集合接口详解
2.1 集合与数组
(1)数组长度固定,集合长度不固定
(2)数组可以存储基本类型和引用类型,集合只能存储引用类型(放入基本类型时,会自动装箱)
2.2 List vs Set
List 接口特点:有序、有下标、元素可重复
Set 接口特点:无序、无下标、元素不能重复
2.3 Collection 接口
特点:代表一组任意类型的对象
public interface Collection<E> extends Iterable<E> {
Iterator<E> iterator();
boolean removeAll(Collection<?> c);
boolean retainAll(Collection<?> c);
}
示例:
@Test
public void demo() {
Collection<String> collection = new ArrayList<>();
collection.add("hello");
collection.add("world");
Iterator<String> iterator = collection.iterator();
while (iterator.hasNext()) {
String next = iterator.next();
if ("world".equals(next)) {
// collection.remove(next); 会抛异常 java.util.ConcurrentModificationException
iterator.remove();
}
}
System.out.println(collection);
}
3. 迭代器
3.1 Iterator 接口
public interface Iterator<E> {
boolean hasNext();
E next();
default void remove() {
throw new UnsupportedOperationException("remove");
}
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}
迭代过程中不能进行删除、添加操作,会抛异常 java.util.ConcurrentModificationException
@Test
public void test() {
List<String> names = new ArrayList<>();
names.add("111");
names.add("222");
for (String name : names) {
if ("111".equals(name)) {
// names.remove("111"); // java.util.ConcurrentModificationException
names.add("333"); // java.util.ConcurrentModificationException
}
}
}
改进:
@Test
public void test() {
List<String> names = new ArrayList<>();
names.add("111");
names.add("222");
Iterator<String> iterator = names.iterator();
while (iterator.hasNext()) {
String next = iterator.next();
if ("222".equals(next)) {
// names.remove(next); // java.util.ConcurrentModificationException
iterator.remove();
}
}
}
3.2 Iterable 接口
- 实现 Iterable 接口,就拥有了获取迭代器的能力
public interface Iterable<T> {
Iterator<T> iterator();
// forEach() 遍历
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
default Spliterator<T> spliterator() {
return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
}
Collection 继承了 Iterable 接口
public interface Collection<E> extends Iterable<E> {
Iterator<E> iterator();
}
3.3 集合里的迭代器
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
public ListIterator<E> listIterator() {
return new ListItr(0);
}
public Iterator<E> iterator() {
return new Itr();
}
// 内部类实现了 Iterator
private class Itr implements Iterator<E> {}
private class ListItr extends Itr implements ListIterator<E> {}
}
public interface List<E> extends Collection<E> {}
3.4 已存在Iterator为何还要Iterable
1.Iterator 接口的核心方法 next(), hashNext() 等,都是严重依赖于指针的,也就是迭代的目前的位置。如果 Collection 直接实现Iterator接口,那么集合对象就拥有了指针的能力,内部不同方法传递,就会让 next() 方法互相受到阻挠。只有一个迭代位置,互相干扰。
2.Iterable 每次获取迭代器,就会返回一个从头开始的,不会和其他的迭代器相互影响。
3.解耦,有些集合不止有一个Iterator内部类,可能有两个,比如ArrayList,LinkedList,可以获取不同的Iterator执行不一样的操作
4. 集合工具类(java.util.Collections)
4.1 sort(...)
public class Collections {
public static <T extends Comparable<? super T>> void sort(List<T> list) {
list.sort(null);
}
public static <T> void sort(List<T> list, Comparator<? super T> c) {
list.sort(c);
}
}
List<Integer> list = Arrays.asList(1, 4, 3);
Collections.sort(list);
// Collections.sort(list, new Comparator<Integer>() {
// @Override
// public int compare(Integer o1, Integer o2) {
// return 0;
// }
// });
Collections.sort(list, (o1, o2) -> o2 - o1);
网友评论