commons-collections4、关于springframework的CollectionUtils包工具类介绍

https://blog.csdn.net/liuerchong/article/details/108556945

package com.baili.demo.test;

import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.collections.Bag;
import org.apache.commons.collections4.map.MultiKeyMap;
import org.apache.commons.collections4.*;
import org.apache.commons.collections4.bag.HashBag;
import org.apache.commons.collections4.bidimap.DualHashBidiMap;
import org.apache.commons.collections4.keyvalue.MultiKey;
import org.apache.commons.collections4.list.*;
import org.apache.commons.collections4.map.FixedSizeMap;
import org.apache.commons.collections4.map.LRUMap;
import org.apache.commons.collections4.map.SingletonMap;
import org.apache.commons.collections4.multimap.ArrayListValuedHashMap;
import org.apache.commons.collections4.multiset.HashMultiSet;
import org.apache.commons.collections4.multiset.PredicatedMultiSet;
import org.apache.commons.collections4.queue.CircularFifoQueue;
import org.junit.Test;


import java.util.*;

@Slf4j
public class CollectionsStudy {

    /* Bag接口定义了一个集合,它可以计算一个对象出现在集合中的次数。 例如,如果Bag包含{a,a,b,c},则getCount("a")方法将返回2,而uniqueSet()返回唯一值。*/
    @Test
    public void testHashBag() {
        Bag hashBag = new HashBag<>();
        String s1 = "s1";
        String s2 = "s2";
        hashBag.add(s1);
        hashBag.add(s1);
        //一次性放置多个元素
        hashBag.add(s2, 3);

        // 获得包中元素迭代器
        Iterator iterator = hashBag.iterator();
        System.out.println("包中元素为:");
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
        System.out.println("包中元素个数为:" + hashBag.size()); //5
        //下面两个特有的方法 使用起来较为方便
        System.out.println("包中entity1个数为:" + hashBag.getCount(s1)); //2
        System.out.println("去重后个数为:" + hashBag.uniqueSet().size()); //2
    }

    @Test
    public void testMultiKey() {
        // MultiKey  多Key Map  功能很简单:装载多个key的一个对象
        MultiKey multiKey = new MultiKey<>("a", "b");
        System.out.println(multiKey); //MultiKey[a, b]

        // 多个键对应一个值 两个key:name和NAME
        MultiKeyMap multiKeyMap = new MultiKeyMap();
        multiKeyMap.put("name", "NAME", "jianggujin");
        System.out.println(multiKeyMap); //{MultiKey[name, NAME]=jianggujin}
        System.out.println(multiKeyMap.get("name")); //null
        System.out.println(multiKeyMap.get("NAME")); //null
        System.out.println(multiKeyMap.get("name", "NAME")); //jianggujin

        //测试key覆盖
        multiKeyMap.put("name", "shixiang", "cover");
        System.out.println(multiKeyMap); //{MultiKey[name, shixiang]=cover, MultiKey[name, NAME]=jianggujin}

        //这样子  value值才会被覆盖
        multiKeyMap.put("name", "NAME", "cover");
        multiKeyMap.put("name", "NAME","NAME3", "cover");
        System.out.println(multiKeyMap); //{MultiKey[name, shixiang]=cover, MultiKey[name, NAME]=cover}
    }

    @Test
    public void testMultiValuedMap() {
   /* MultiValuedMap:多值Map ; 一个key可对应多个值,内部的数据结构逻辑交给它去维护。
    我们平时使用的Map>这种数据结构,就可以被这种代替,使用起来非常方便
            ArrayListValuedHashMap  见名之意,values采用ArrayList来存储
 */
        MultiValuedMap map = new ArrayListValuedHashMap<>();

        map.put("key1", "value1");
        System.out.println(map); //{key1=[value1]}
        map.put("key1", "value11111");
        System.out.println(map); //{key1=[value1, value11111]}
        log.info("----------1---------");
        Collection values = map.values();
        System.out.println(values); //[value1, value11111]
        log.info("----------2---------");
        //map.remove("key1");
        //System.out.println(map); //{}

        //强悍 可以直接干掉values里的某一个值
            map.removeMapping("key1", "value1");
        System.out.println(map); //{key1=[value11111]}
        log.info("---------3---------");
        //一次性放多个value
        map.putAll("key2", Arrays.asList("fang", "shi", "xiang"));
        System.out.println(map); //{key1=[value11111], key2=[fang, shi, xiang]}
        log.info("---------4----------");
        //get方法  返回List
        Collection collection = map.get("key2");
        MultiSet keys = map.keys();
        Set strings = map.keySet();
        System.out.println(keys); //[key1:1, key2:3] //后面的数字表示对应的value的数量
        System.out.println(strings); //[key1, key2]
        System.out.println(map.size()); //4 注意此处的size,是所有value的size 不是key的
        System.out.println(collection); //[fang, shi, xiang]


          /*
        HashSetValuedHashMap
        基本用法同上,但是很显然values用set去存储。那就无序,但是去重了
        这些多值的Map的key,都是采用HashMap的结构存储的
        MultiMapUtils提供一些基础工具方法:emptyMultiValuedMap、unmodifiableMultiValuedMap、newListValuedHashMap、getValuesAsSet、getValuesAsList等等
    */

    }

    @Test
    public void testHashMultiSet() {
    /*
       HashSetValuedHashMap
        基本用法同上,但是很显然values用set去存储。那就无序,但是去重了
        这些多值的Map的key,都是采用HashMap的结构存储的
        MultiMapUtils提供一些基础工具方法:emptyMultiValuedMap、unmodifiableMultiValuedMap、newListValuedHashMap、getValuesAsSet、getValuesAsList等等
       MultiSet
        set我们都知道,它是无序的,并且是不允许出现重复元素的。
        但有些场景我们不需要顺序,但是我们需要知道指定key出现的个数(比如每样产品ID对应的剩余数量这种统计信息),那么用MultiSet统计是一个很好的方案
      HashMultiSet
        底层实现原理为HashMap和MutableInteger
    */
        MultiSet set = new HashMultiSet<>();

        set.add("fang");
        set.add("fang");
        set.add("shi");
        set.add("xiang");
        set.add("xiang");
        set.add("xiang");

        //我们发现此set是无序的,但是允许了重复元素的进入 并且记录了总数
        System.out.println(set); //[shi:1, xiang:3, fang:2]
        System.out.println(set.size()); //6 = 1+3+2

        //批量添加  一些字就添加N个
        set.add("test",5);
        System.out.println(set); //[test:5, shi:1, xiang:3, fang:2]

        //移除方法
        System.out.println(set.getCount("fang")); //2
        set.remove("fang");
        //此移除 一次性只会移除一个
        System.out.println(set.getCount("fang")); //1
        //一次性全部移除 N个
        set.remove("xiang", set.getCount("xiang"));
        System.out.println(set.getCount("xiang")); //0  已经被全部移除了

        //removeAll 吧指定的key,全部移除
        set.removeAll(Arrays.asList("fang","shi","xiang","test"));
        System.out.println(set); //[]
    }
    @Test
    public void testFixedSizeList() {
//        PredicatedMultiSet 使用较少,不做讲解
//        BoundedCollection:有限制的集合
//        继承自Collection,他提供了一些列的有用的实现
//        FixedSizeList:固定长度大小的List
    /*FixedSizeList:固定长度大小的List*/
        FixedSizeList c = FixedSizeList.fixedSizeList(Arrays.asList("fang", "shi", "xiang"));

        System.out.println(c); //[fang, shi, xiang]
        System.out.println(c.size()); //3

        //c.remove("fang"); //java.lang.UnsupportedOperationException: List is fixed size
        //c.add("fang"); //UnsupportedOperationException: List is fixed size

        //虽然不能增加和删除 但可以改
        c.set(2, "heng");
        System.out.println(c); //[fang, shi, heng]
        System.out.println(c.get(2));

        //BoundedCollection提供的两个方法
        boolean full = c.isFull();//如果是FixedSizeList 永远返回true 因为大小肯定是固定的
        int size = c.maxSize();//值同size()方法

    }

   @Test
   public void testFixedSizeMap() {
        /*
        BoundedMap:
        FixedSizeMap
        */
        FixedSizeMap m = FixedSizeMap.fixedSizeMap(new HashMap() {{
            put("fang", "a");
            put("shi", "b");
            put("xiang", "c");
        }});

        System.out.println(m); //{shi=b, xiang=c, fang=a}
        System.out.println(m.size()); //3

        //不能再往里面添加数据了
        //m.put("aaa", "aaa"); //java.lang.IllegalArgumentException: Cannot put new key/value pair - Map is fixed size

        //在我没有改变长度的情况下 是可以修改的
        m.put("fang", "aaaaaaaa");
        System.out.println(m); //{shi=b, xiang=c, fang=aaaaaaaa}

    }

    @Test
    public void testLRUMap() {
        /*
         FixedSizeSortedMap
        区别:底层采用SortedMap
        LRUMap
        底层是LRU算法
        LRU算法的设计原则是:如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小。也就是说,当限定的空间已存满数据时,应当把最久没有被访问到的数据淘汰。
        */

        LRUMap map = new LRUMap<>(3);

        System.out.println(map); //{}
        System.out.println(map.size()); //0
        System.out.println(map.maxSize()); //3
        System.out.println(map.isFull()); //false

        map.put("fang", "a");
        map.put("shi", "b");
        map.put("xiang", "c");

        System.out.println(map); //{fang=a, shi=b, xiang=c}
        System.out.println(map.size()); //3
        System.out.println(map.maxSize()); //3
        System.out.println(map.isFull()); //true

        //虽然满了 但还是可以往里面塞数据

        //如果我们都没有get使用过 那就从后往前挤出来吧
        //map.put("heng", "heng");
        //map.put("heng22", "heng22");
        //System.out.println(map); //{xiang=c, heng=heng, heng22=heng22}
        //System.out.println(map.size()); //3
        //System.out.println(map.maxSize()); //3
        //System.out.println(map.isFull()); //true

        //我此处多次使用xiang这个key 我们会发现  xiang这个key就不会被挤出来
        map.get("xiang");
        map.get("xiang");

        map.put("heng", "heng");
        map.put("heng22", "heng22");

        System.out.println(map); //{xiang=c, heng=heng, heng22=heng22}

        System.out.println(map.size()); //3
        System.out.println(map.maxSize()); //3
        System.out.println(map.isFull()); //true

    }


    @Test
    public void testCircularFifoQueue() {
        /*  环形的先进先出队列
            UnmodifiableBoundedCollection:不能修改的List
            CircularFifoQueue:环形的先进先出队列
            当达到指定的size长度后,符合FIfo先进先出的原则被环形覆盖
        * */
        CircularFifoQueue c = new CircularFifoQueue<>(3);

        // 这个size二和MaxSize就有差异化了
        System.out.println(c.size()); //0
        System.out.println(c.maxSize()); //3

        c.add("fang");
        c.add("shi");
        c.add("xiang");

        //我们发现虽然长度是3  但是因为循环的特性 再添加一个并不会报错  而是 先进的先被挤出了
        c.add("heng");
        System.out.println(c); //[shi, xiang, heng]

        // 继续添加 就会把前面的继续挤出来 满员了之后,符合先进先出的原则
        c.add("heng2");
        c.add("heng3");
        System.out.println(c); //[heng, heng2, heng3]

    }



    @Test
    public void testSingletonMap() {
   // SingletonMap   单例模式Map
        SingletonMap map = new SingletonMap<>();
        System.out.println(map); //{null=null}
        //size已经是1了
        System.out.println(map.size()); //1
        System.out.println(map.maxSize()); //1

        //哪怕一个都没有 也不能设置值
        //map.put("one","one"); //Cannot put new key/value pair - Map is fixed size singleton

        //虽然不能再放key 但可以改值
        map.setValue("xiang"); //{null=xiang}
        System.out.println(map);

        //一般建议在构造的时候,就给key和value赋值  如下:
        map = new SingletonMap<>("fang", "shixiang");
        System.out.println(map); //{fang=shixiang}
    }



    @Test
    public void testDualHashBidiMap() {
        /*
        在项目当中,经常出现需要根据Key值获取value;而且要求根据value获取key值
        BidiMap: 双重Map 使用双向映射,可以使用值查找键,并且可以使用键轻松查找值。(自然,它可以根据key移除,也可以根据value移除)
            该场景使用还是比较多的,比如一对一的映射关系,都可以使用这来存储。如果你使用HashMap,那你得维护两个,还是比较麻烦的
            public interface BidiMap extends IterableMap {}
            也是个普通的Map。继承IterableMap增加了一种迭代方式,例子里会有讲解
        DualHashBidiMap
            底层维护两个HashMap,一个正向,一个逆向来达到效果的。
            public DualHashBidiMap() {  super(new HashMap(), new HashMap());  }
            public DualHashBidiMap(final Map map) {
                    super(new HashMap(), new HashMap());
                    putAll(map);
                }
        * */

    /*     DualLinkedHashBidiMap   底层采用两个LinkedHashMap存储,其余同上
          DualTreeBidiMap 底层采用两个TreeMap存储,其余同上
             它不要求key和value都是实现了比较器接口的,但是自己可以自定义比较器接口传进去

         TreeBidiMap
        注意TreeBidiMap和DualTreeBidiMap的区别
        TreeBidiMap采用是红黑树:Node。一个node就是put的一个键值对,这样子来实现双端的Map,底层的原理和上面的不一样。这样的好处:可以最大程度的节约存储空间,从而提高效率。

        firstKey、lastKey、nextKey等等都有一套自己的实现,处理效率还是蛮高的
        备注:使用起来基本同上,因此实例省略  此Map要求key和value必须必须必须都实现了比较器接口
    */
        BidiMap map = new DualHashBidiMap<>();
        map.put("key1", "value1");
        map.put("key2", "value2");
        map.put("key3", "value3");

        //多出来的一种遍历方式  还是非常人性化的
        MapIterator it = map.mapIterator();
        while (it.hasNext()) {
            it.next(); //此句话必须调用  返回的是key,效果同getKey,但必须调用
            System.out.println(it.getKey() + "---" + it.getValue());
        }
        log.info("---------1----------");
        System.out.println(map.get("key1")); //value1
        //根据value拿key
        System.out.println(map.getKey("value1")); //key1
        //这个方法是Map接口的
        String orDefault = map.getOrDefault("k", "Default Value");
        System.out.println(map.getOrDefault("k", "Default Value")); //Default Value
        //返回一个逆序的视图  注意是视图
        BidiMap inverseMap = map.inverseBidiMap();

        //根据key删除
        inverseMap.remove("key1");
        //根据value删除
        inverseMap.removeValue("value2");

        System.out.println(map); //{key1=value1, key2=value2, key3=value3}
        System.out.println(inverseMap); //{value2=key2, value1=key1, value3=key3}

//    输出:
//    key1---value1
//    key2---value2
//    key3---value3
//            value1
//    key1
//            defaultValue
//    {key1=value1, key2=value2, key3=value3}
//    {value2=key2, value1=key1, value3=key3}

    }

    @Test
    public void testGrowthList() {
    /*
        GrowthList LazyList :list自增长效果
        GrowthList修饰另一个列表,可以使其在因set或add操作造成索引超出异常时无缝的增加列表长度,
        可以避免大多数的IndexOutOfBoundsException。(下标越界)

        备注:LazyList修饰另一个列表,当调用get方法时,如果索引超出列表长度,列表会自动增长,
        我们可以通过一个工厂获得超出索引位置的值。LazyList和GrowthList都可以实现对修饰的列表进行增长,
        但是LazyList发生在get时候,而GrowthList发生在set和add时候,我们也可以混合使用这两种列表。
    */

        List src = new ArrayList<>();
        src.add("11");
        src.add("22");
       // src.set(5,"22");//java.lang.IndexOutOfBoundsException: Index 5 out of bounds for length 2
        src = GrowthList.growthList(src);
        System.out.println(src);

        // 经过GrowthList.growthList一修饰后  这个list能够最大程度的避免空数组越界问题  有时候还是挺有用的
        // 索引超出,自动增长 空索引位 补 null
        src.set(5, "44");
        System.out.println(src); //[11, 22, null, null, null, 44]

        //LazyList修饰 列表,当调用get方法时
        src = LazyList.lazyList(src, new Factory() {
            @Override
            public String create() {
                return null;
            }
        });

        //src.set(9, "944"); //不报错是
        System.out.println(src);
        System.out.println(src.get(7));
    }

    @Test
    public void testSetUniqueList() {
    /*

        SetUniqueList
        SetUniqueList实现了一个不允许重复元素的列表,有点和Set类似。
        但是由有List,保证了顺序
    */
        List list = new ArrayList<>();
        list.add("fang");
        list.add("shi");
        list.add("shi");
        list.add("xiang");
        System.out.println(list); //[fang, shi, shi, xiang]
        //list.get(5);//java.lang.IndexOutOfBoundsException: Index 5 out of bounds for length 4

        //完美实现去重 且还完美保证了顺序
        list = SetUniqueList.setUniqueList(list);
        System.out.println(list); //[fang, shi, xiang]

        // 但是需要注意 因为已经是SetUniqueList 类型了  这个时候add相同元素就不再好使了
        list.add("shi");
        System.out.println(list); //[fang, shi, xiang]


    }

    @Test
    public void testTreeList() {
//    我表示这个List在我们既希望去重,有需要保持原来顺序的时候,特别特别好用。装饰一下就行,使用也非常方便
//      TreeList
//    TreeList实现了优化的快速插入和删除任何索引的列表。这个列表内部实现利用树结构,确保所有的插入和删除都是O(log n)。
        List list = new TreeList<>();
        list.add("fang");
        list.add("shi");
        list.add("shi");
        list.add("xiang");
        System.out.println(list); //[fang, shi, shi, xiang]

    }

    @Test
    public void testpartition() {
//    partition:切割 把一个大的List切割成多个List 非常好用
//    常用场景:有10000个id需要批量查询,我们可以切割一下,200个发一次请求去查询一次,还可以开多个线程,用闭锁去弄
        List list1 = new ArrayList(){{
            add("a");
            add("b");
            add("c");

            add("a");
            add("b");
            add("c");

            add("a");
            add("b");
            add("c");
        }};

        List> partition = ListUtils.partition(list1, 4);

        System.out.println(partition); //[[a, b, c, a], [b, c, a, b], [c]]
    }

    @Test
    public void testListUtils() {
    //  List工具类:  ListUtils   emptyIfNull:同上
    //    defaultIfNull:可以在为null的时候,自己给个默认值返回
    //    fixedSizeList:不解释
    //    hashCodeForList:给List吧它的HashCode计算出来
    //    intersection:取交集,生成一个新的List
        List list1 = new ArrayList(){{
            add("a");
            add("b");
            add("c");
        }};
        List list2 = new ArrayList(){{
            add("c");
            add("d");
            add("e");
        }};

        //两个列表的交集
        //取出交集 并且返回一个新的List
        // 返回一个新列表,该列表包含两个给定列表中包含的所有元素。
        List intersection = ListUtils.intersection(list1, list2);
        System.out.println(intersection); //[c]
    // ubtract:相当于做减法,用第一个List除去第二个list里含有的元素 ,然后生成一个新的list
        // 从第一个列表中减去第二个列表中的所有元素,将结果放入新列表中。
        // 并且返回一个新的List
        List subtract = ListUtils.subtract(list1, list2);
        System.out.println("subtract"+subtract); //[a,b]

        //这个方法也能取出交集的效果 但是会直接改变list1里面的元素  list2不变 (污染原来的集合)
//        list1.retainAll(list2);
//        System.out.println(list1); // [c]
//        System.out.println(list2); //[c, d, e]



        //取出并集 并且返回一个新的List   此方法 有相加的功能和去重的功能,很多场景还是很好用的
        List sumlist = ListUtils.sum(list1, list2);

        System.out.println(sumlist); //[a, b, c, d, e]

    }



    @Test
    public void testSetUtils() {
    //Set工具类: SetUtils
    //difference:找到两个set之间的不同元素
    //返回的是第一个set里有的,但是第二个set里没有的元素们
        Set set = new HashSet();
        Set set1 = new HashSet() {{
            add("a");
            add("b");
            add("c");
        }};
        Set set2 = new HashSet() {{
            add("c");
            add("d");
            add("e");
        }};

        SetUtils.SetView difference = SetUtils.difference(set1, set2);
        System.out.println(difference); //[a,b]

        Set strings = difference.toSet();
        System.out.println(strings); //[a,b]

    //disjunction:和上面方法类似,但是属于加强版
    //会返回第一个set和第二个有差异的所有元素们  {感觉类似交集取反}
        SetUtils.SetView disjunction = SetUtils.disjunction(set1, set2);
        System.out.println(disjunction); //[a, b, d, e]

        Set strings1 = disjunction.toSet();
        System.out.println(strings1); //[a, b, d, e]

        //emptyIfNull:与 MapUtils类似方法
        // .emptyIfNull(set) 如果参数为null,则返回一个可变的空映射,否则返回参数本身。
        // 好像啥也没变 ???
        Set sets = SetUtils.emptyIfNull(strings1);
          set = SetUtils.emptyIfNull(set);
        set.add("key8");
        set.add("key7");
        set.add("key6");
        set.add("key5");
        set.add(null);
        set.add(null);
        System.out.println(set);
        // emptySortedSet  一个不可修改的空排序集
        SortedSet sortedSet = SetUtils.emptySortedSet();
       // sortedSet.add("key8"); // java.lang.UnsupportedOperationException

        System.out.println(sortedSet);
        // 使用Set.hashCode()中指定的算法生成哈希代码。 返回 hashCode : 13154014
        System.out.println(SetUtils.hashCodeForSet(set));


        //  可以K,V 为空的 线程安全的 MAP Set
        Map map = Collections.synchronizedMap(new IdentityHashMap());
        Set synchronizedSet = Collections.synchronizedSet(SetUtils.newIdentityHashSet());


    //isEqualSet:
    //两个set里面的元素是否都一样(长度一样、元素一样),有时候判断还是非常有用的
    //union:合并两个set,生成一个新的set
        boolean equalSet = SetUtils.isEqualSet(set1, set2);
        System.out.println(equalSet);
        //类似于addAll的效果,但是它的好处是生成了一个新的set,对原来的set没有污染。
        SetUtils.SetView union = SetUtils.union(set1, set2);

        System.out.println(union); //[a, b, c, d, e]
        System.out.println(set1); //[a, b, c, d, e]
        System.out.println(set2); //[a, b, c, d, e]

    }

    @Test
    public void testMapUtils() {
    //Map工具类:MapUtils
        // 一个空的 MAP
        HashMap map = new HashMap<>();
        System.out.println(map);
        //返回一个空的 MAP
        Map objectMap = Collections.emptyMap();
        System.out.println(objectMap); // {} 返回一个空的 MAP

        map.put("key1", "value1");
        map.put("key2", "value2");
        map.put("key5", "value5");
        map.put("key3", "value3");
        //MapUtils.emptyIfNull(map) 如果参数为null,则返回一个不可变的空映射,否则返回参数本身。
        System.out.println( MapUtils.emptyIfNull(map)); //{} / {key1=value1, key2=value2, key5=value5, key3=value3}
        // if (map == null)  put 元素报错  Map is fixed size
        //map.put("key8", "emptyIfNull");
        // java.lang.IllegalArgumentException: Cannot put new key/value pair - Map is fixed size
        // if (map != null) put 元素不报错
        //map.put("key8", "emptyIfNull");
        log.info("-----------------------------------------");

        //fixedSizeMap、fixedSizeSortedMap
        Map sizeMapap = MapUtils.fixedSizeMap(map);
        System.out.println(sizeMapap);
        System.out.println(sizeMapap.size()); //

        //不能再往里面添加数据了
        // 固定长 后在put  报 Cannot put new key
        //m.put("aaa", "aaa"); //java.lang.IllegalArgumentException: Cannot put new key/value pair - Map is fixed size

        //在我没有改变长度的情况下 是可以修改的
        sizeMapap.put("key5", "aaaaaaaa");
        System.out.println(sizeMapap); //{key1=value1, key2=value2, key5=aaaaaaaa, key3=value3}
        log.info("-----------------------------------------");


        log.info("--------------------invertMap---------------------");
       // invertMap  对调key和value的值
        Map maps = new HashMap<>();
        maps.put("key1", "value1");
        maps.put("key2", "value2");
        maps.put("key3", "value3");
        System.out.println(maps);
        //fanzhuan反转  对调key和value
        Map invertMap = MapUtils.invertMap(maps);
        System.out.println(invertMap); //{key1=value1, key2=value2, key3=value3}
        log.info("-----------------------------------------");


        log.info("--------------------iterableMap---------------------");
        //iterableMap 构建一个iterableMap,然后方便遍历、删除等等
        //之前我们需要遍历删除Map中元素,需要
        // 然后在根据key的迭代器去删除   map.entrySet().iterator();

        Map map2 = new HashMap<>();
        map2.put("key1", "value1");
        map2.put("key2", "value2");
        map2.put("key3", "value3");
        // 现在
        IterableMap iterableMap = MapUtils.iterableMap(map2);
        MapIterator it = iterableMap.mapIterator();
        MapIterator iterator = MapUtils.iterableMap(map2).mapIterator();
//        while (iterator.hasNext()){
//        }
        while (it.hasNext()){
            it.next();
            String key = it.getKey();
            if(key.equals("key2")){
                it.remove();
            }
        }
        System.out.println(iterableMap); //{key1=value1, key3=value3}
        //我们发现这样对it Map进行删除  原来的Map也会达到同样的效果
        System.out.println(map2); // {key1=value1, key3=value3}

        log.info("-----------------------------------------");


        log.info("--------------------populateMap---------------------");
        //populateMap
        //能很方便向Map里面放值,并且支持定制化key和value,还是挺好用的
        //同时该方法也提供了对MutiMap的支持
        Map map3 = new HashMap<>();
        map3.put("key1", "value1");

        //序列化 根据提供的values,按照后面规则把key都生成出来然后直接放进去
        MapUtils.populateMap(map3, Arrays.asList("a", "b", "c"), e -> "key-" + e);
        System.out.println(map3); //{key1=value1, key-a=a, key-c=c, key-b=b}
        //可以在上面的理论上 对value进行进一步操作  不能采用map.values() 否则由于并发修改异常
        // MapUtils.populateMap(map, map.values(), e -> e, e -> "value-" + e); //java.util.ConcurrentModificationException
        MapUtils.populateMap(map3, Arrays.asList("a", "b", "c"), e -> e, e -> "value-" + e); //java.util.ConcurrentModificationException

        System.out.println(map3); //{key1=value1, key-a=a, a=value-a, b=value-b, c=value-c, key-c=c, key-b=b}

        log.info("-----------------------------------------");


        log.info("--------------------toProperties---------------------");
//        synchronizedMap、unmodifiableMap
//        toProperties:可以有非常简便的转化

        map3.put(null,"ooo");
        map3.put("ooo",null);
        System.out.println(map3);
        //获取用Map中的值初始化的新(Properties)资源对象。空输入将返回空的(Properties)资源对象。
        // (Properties)对象只能存储非空键和值,因此,如果提供的映射包含空键或值,则会抛出NullPointerException。
        Properties properties = MapUtils.toProperties(map3);
        System.out.println(properties); //{key3=value2, key2=value2, key1=value1}



    }



    public static void main(String[] args) {


    }
}

你可能感兴趣的:(java,apache,servlet)