欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

第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
  1. 迭代器的指针指向元素位置之前:
    第17章 容器深入研究
    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异常。

本文地址:https://blog.csdn.net/qq_43183860/article/details/107676199

相关标签: Thinking In Java