第17章 容器深入研究

  1. 迭代器的指针指向元素位置之前:
    在这里插入图片描述
    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 
        }

  1. 专用于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( )方法必须紧跟在访问一个元素之后执行,否则会引发异常。

  1. 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( )方法是完全相同的,所以编译期会报错。

  1. IdentityHashMap不使用equals( )来比较元素,而是直接使用"=="。
  2. HashMap和HashSet都具有允许你指定负载因子的构造器,当负载情况达到该负载因子的水平时,容器将自动增加容量,实现方式是使容量大致加倍,并重新将现有对象分布到新的桶位集中(再散列)。HashMap的默认负载因子为0.75,更高的负载因子可以降低表所需空间,但是会增加查找的代价。
  3. Java容器类类库采用快速报错机制(fail-fast)。它会探查容器上的任何除了你的进程所进行的操作之外的所有变化,一旦发现其他进程修改了容器,就会立刻抛出ConcurrentModificationException异常。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值