第17章 容器深入研究
程序员文章站
2022-07-10 19:03:13
迭代器的指针指向元素位置之前: public static void test01() { List list = new ArrayList<>(); list.add("1"); list.add("2"); list.add("3"); // 初始化指针指向第0个元素(元素从0开始计数)之前(默认): // ListIterator
- 迭代器的指针指向元素位置之前:
public static void test01() {
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
// 初始化指针指向第0个元素(元素从0开始计数)之前(默认):
// ListIterator<String> it = list.listIterator(0);
// 初始化指针指向第3个元素之前:
ListIterator<String> it = list.listIterator(3);
while (it.hasPrevious()) {
System.out.print(it.previous()); // 321
}
- 专用于List的迭代器ListIterator对象可以对List进行增删改操作:
public static void test01() {
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
// 初始化指针指向第0个元素(从0开始计数)之前(默认):
// ListIterator<String> it = list.listIterator(0);
// 初始化指针指向第2个元素之前:
ListIterator<String> it = list.listIterator(2);
// 初始化后不能立即remove和set,因为没有访问过任何元素:
//! it.remove();
//! it.set("5");
// 添加:
it.add("4"); // list = [1, 2, 4, 3]
// 访问元素"3",然后删除:
it.next();
it.remove(); // list = [1, 2, 4]
// 访问元素"4",然后更改为"5":
it.previous();
it.set("5"); // list = [1, 2, 5]
System.out.println("list = " + list);
}
其中remove( )和set( )方法必须紧跟在访问一个元素之后执行,否则会引发异常。
- LinkHashMap散列化所以元素,但是在遍历键值对时,却又以元素的插入顺序返回键值对。此外,LinkHashMap还可以采用基于访问的最近最少使用(LRU)算法,最少访问的元素将出现在输出队列的前面。
public static void test03() {
// 初始化容量16,负载因子0.75,启用LRU算法:
LinkedHashMap<Integer, String> lhm = new LinkedHashMap<>(16,0.75f,true);
lhm.put(1, "1");
lhm.put(2, "2");
lhm.put(3, "3");
// 按照插入顺序输出:
System.out.println(lhm); // {1=1, 2=2, 3=3}
// 先访问1
lhm.get(1);
// 再访问2
lhm.get(2);
// 可以看到,最近访问的2排到了队列末尾:
System.out.println(lhm); // {3=3, 1=1, 2=2}
}
class SlowMap<K, V> extends AbstractMap<K, V> {
@Override
public Set<Entry<K, V>> entrySet() {
return null;
}
private List<K> keys = new ArrayList<>();
private List<V> values = new ArrayList<>();
public V put(K key, V value) {
V oldValue = get(key);
if (!keys.contains(key)) {
keys.add(key);
values.add(value);
}else {
values.set(keys.indexOf(key), value);
}
return oldValue;
}
@Override
public V get(Object key) {
return null;
}
}
SlowMap<K, V>类其中一个方法get( )的参数类型使用Object而不使用泛型K的原因:SlowMap<K, V>中的get( )方法继承自AbstractMap<K, V>,若使用泛型K作为参数类型,就不能覆盖父类的方法,但是擦除会使得K变为Object,运行时与父类的get( )方法是完全相同的,所以编译期会报错。
- IdentityHashMap不使用equals( )来比较元素,而是直接使用"=="。
- HashMap和HashSet都具有允许你指定负载因子的构造器,当负载情况达到该负载因子的水平时,容器将自动增加容量,实现方式是使容量大致加倍,并重新将现有对象分布到新的桶位集中(再散列)。HashMap的默认负载因子为0.75,更高的负载因子可以降低表所需空间,但是会增加查找的代价。
- Java容器类类库采用快速报错机制(fail-fast)。它会探查容器上的任何除了你的进程所进行的操作之外的所有变化,一旦发现其他进程修改了容器,就会立刻抛出ConcurrentModificationException异常。
本文地址:https://blog.csdn.net/qq_43183860/article/details/107676199