笔记

java.util包提供了集合类:Collection。它是除Map外所有其他集合类的根接口。List:一种有序列表的集合。Set:一种保证没有重复元素的集合。Map:一种通过键值(key-value)查找的映射表集合。Hashtable:一种线程安全的Map实现;Vector:一种线程安全的List实现;Stack:基于Vector实现的LIFO的栈。Enumeration<E>:已被Iterator取代。List类就像数组一样,提供两个实现:
具体区别:

LinkedList 即实现了 List 接口,又实现了 Queue 接口。
of()方法:jdk9之后才开始存在。
List.of(1, 2, "1", true);
我们应当坚持使用迭代器==iterator或者forEach==循环遍历 List,因为它俩总能根据不同的类型提供最快的遍历速度。
Iterator对象有两个方法:
boolean hasNext()判断是否有下一个元素E next()返回下一个元素数组与 List 之间的相互转换:
Integer[] num={1,2,3};
// 1. asList()
List<Integer> list = Arrays.asList(num);
// 2. of()
List<Integer> list = List.of(num);
List<Integer> list = List.of(1,2,3);
// toArray()的参数标识:类型 + 大小
Integer[] array = list.toArray(new Integer[list.size()]);
Map 跟 List一样,只是一个接口,最常用的实现类是 HashMap。
HashMap不保证数据存储的顺序,TreeMap保证。
如果 key 不存在,将返回 null。
简单遍历 Map
keySet()==遍历:Map<Integer,String > maps=new HashMap<>();
maps.put(1,"a");maps.put(2,"b");maps.put(3,"c");
for (Integer key:maps.keySet()){
String value = maps.get(key);
System.out.println(value);
}
entrySet()==遍历Map<Integer,String > maps=new HashMap<>();
maps.put(1,"a");maps.put(2,"b");maps.put(3,"c");
for (Map.Entry<Integer, String > map : maps.entrySet()){
System.out.println(map.getKey()+map.getValue());
}
HashMap原理

EnumMap:一种基于枚举类的 Map。
TreeMap
equals()和hashCode()(因为有序无需此)。Map<Person, Integer> map = new TreeMap<>(new Comparator<Person>() {
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
Properties
Hashtable,它的设计实际上存在问题,但是为了保持兼容性,现在已经无法更改。last_open_file = /data/hello.txt
auto_save_interval = 60
load()读取文件;getProperty()获取配置。String f = "setting.properties";
Properties props = new Properties();
// load()默认总是以ASCII编码读取字节流,所以会导致读到乱码
props.load(new FileReader("settings.properties", StandardCharsets.UTF_8));
String filepath = props.getProperty("last_open_file");
String interval = props.getProperty("auto_save_interval", "120");
Properties props = new Properties();
props.setProperty("url", "http://www.liaoxuefeng.com");
props.setProperty("language", "Java");
props.store(new FileOutputStream("./setting.properties"), "这是写入的注释");
Set只是接口,具体实现有hashSet、TreeSet(前者不保证顺序)。
Set用于存储不重复的元素集合,实际上相当于只存储key、不存储value的Map
HashSet仅仅是对HashMap的一个简单封装。

Queue只是一个接口,具体的实现有PriorityQueue、Deque、Stack。
Queue接口定义了几个方法,分别为:
(注意到三次存在两种方法,不同之处在于)
| throw Exception | 返回false或null | |
|---|---|---|
| 添加元素到队尾 | add(E e) | boolean offer(E e) |
| 取队首元素并删除 | E remove() | E poll() |
| 取队首元素但不删除 | E element() | E peek() |
使用 remove()之类的操作需要编写 try语句,而 poll()则需要编写if语句。
PriorityQueue
PriorityQueue<String> queue = new PriorityQueue<>();
queue.offer("C");
queue.offer("B");
queue.offer("A");
System.out.print(queue.poll() + queue.poll() + queue.poll());
// 输出:ABC
Deque
ArrayDeque和LinkedList==。offer(),而是调用offerLast()。
LinkedList全能选手,既可以作链表List,也可以作Queue、Deque、Stack。
Stack
push(E);pop();peek()。Java的集合类都可以使用for each循环。
List、Set和Queue会迭代每个元素,Map会迭代每个key。
forEach循环和iterator是同源的:
List<String> list = List.of("Apple", "Orange", "Pear");
for (String s : list) {
System.out.println(s);
}
List<String> list = List.of("Apple", "Orange", "Pear");
for (Iterator<String> it = list.iterator(); it.hasNext(); ) {
String s = it.next();
System.out.println(s);
}
自定义iterator迭代器
// 总是倒序输出
class ReverseIterator implements Iterator<T> {
int index;
ReverseIterator(int index) {
this.index = index;
}
@Override
public boolean hasNext() {
return index > 0;
}
@Override
public T next() {
index--;
return ReverseList.this.list.get(index);
}
}
注意是Collections,而不是Collection。
JDK提供的工具类
常用方法
排序:Collections.sort(list);
洗牌:Collections.shuffle(list);
封装成不可变集合:Collections.unmodifiableList/Map/Set(mutable);
但是,继续对原始的可变List进行增删是可以的,并且,会直接影响到封装后的“不可变”List。所以在转换过后,我们最好立刻扔掉原始的List引用(赋值为 null )。