【小家java】Java之Apache Commons-Collections4使用精讲(Bag、Map、List、Set全覆盖)(中)

简介: 【小家java】Java之Apache Commons-Collections4使用精讲(Bag、Map、List、Set全覆盖)(中)

MultiValuedMap:多值Map



一个key可对应多个值,内部的数据结构逻辑交给它去维护。

我们平时使用的Map<String,List<Long>>这种数据结构,就可以被这种代替,使用起来非常方便

ArrayListValuedHashMap


见名之意,values采用ArrayList来存储


    public static void main(String[] args) {
        MultiValuedMap<String, String> map = new ArrayListValuedHashMap<>();
        map.put("key1", "value1");
        System.out.println(map); //{key1=[value1]}
        map.put("key1", "value11111");
        System.out.println(map); //{key1=[value1, value11111]}
        Collection<String> values = map.values();
        System.out.println(values); //[value1, value11111]
        //map.remove("key1");
        //System.out.println(map); //{}
        //强悍 可以直接干掉values里的某一个值
        map.removeMapping("key1", "value1");
        System.out.println(map); //{key1=[value11111]}
        //一次性放多个value
        map.putAll("key2", Arrays.asList("fang", "shi", "xiang"));
        System.out.println(map); //{key1=[value11111], key2=[fang, shi, xiang]}
     //get方法  返回List
        Collection<String> collection = map.get("key2");
        MultiSet<String> keys = map.keys();
        Set<String> 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等等


MultiSet


set我们都知道,它是无序的,并且是不允许出现重复元素的。

但有些场景我们不需要顺序,但是我们需要知道指定key出现的个数(比如每样产品ID对应的剩余数量这种统计信息),那么用MultiSet统计是一个很好的方案


HashMultiSet


底层实现原理为HashMap和MutableInteger


    public static void main(String[] args) {
        MultiSet<String> 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); //[]
    }


PredicatedMultiSet 使用较少,不做讲解


BoundedCollection:有限制的集合


继承自Collection,他提供了一些列的有用的实现


FixedSizeList:固定长度大小的List


    public static void main(String[] args) {
        FixedSizeList<String> 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提供的两个方法
        c.isFull(); //如果是FixedSizeList 永远返回true 因为大小肯定是固定的
        c.maxSize(); //值同size()方法
    }


UnmodifiableBoundedCollection:不能修改的List

CircularFifoQueue:环形的先进先出队列

当达到指定的size长度后,符合FIfo先进先出的原则被环形覆盖


    public static void main(String[] args) {
        CircularFifoQueue<String> c = new CircularFifoQueue<>(3);
        // 这个siz二和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]
    }


BoundedMap:

FixedSizeMap
    public static void main(String[] args) {
        FixedSizeMap<String, String> m = FixedSizeMap.fixedSizeMap(new HashMap<String, String>() {{
            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}
    }


FixedSizeSortedMap

区别:底层采用SortedMap


LRUMap

底层是LRU算法


LRU算法的设计原则是:如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小。也就是说,当限定的空间已存满数据时,应当把最久没有被访问到的数据淘汰。

    public static void main(String[] args) {
        LRUMap<Object, Object> 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
    }


SingletonMap


    public static void main(String[] args) {
        SingletonMap<String, String> 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}
    }


GrowthList LazyList :list自增长效果


GrowthList修饰另一个列表,可以使其在因set或add操作造成索引超出异常时无缝的增加列表长度,可以避免大多数的IndexOutOfBoundsException。


    public static void main(String[] args) {
        List<String> src = new ArrayList<>();
        src.add("11");
        src.add("22");
        src = GrowthList.growthList(src);
        System.out.println(src);
        //经过GrowthList.growthList一修饰后  这个list能够最大程度的避免空数组越界问题  有时候还是挺有用的
        // 索引超出,自动增长
        src.set(4, "44");
        System.out.println(src); //[11, 22, null, null, 44]
    }


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


SetUniqueList

SetUniqueList实现了一个不允许重复元素的列表,有点和Set类似。但是由有List,保证了顺序


    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("fang");
        list.add("shi");
        list.add("shi");
        list.add("xiang");
        System.out.println(list); //[fang, shi, shi, xiang]
        //完美实现去重 且还完美保证了顺序
        list = SetUniqueList.setUniqueList(list);
        System.out.println(list); //[fang, shi, xiang]
        // 但是需要注意 因为已经是SetUniqueList 类型了  这个时候add相同元素就不再好使了
        list.add("shi");
        System.out.println(list); //[fang, shi, xiang]
    }


我表示这个List在我们既希望去重,有需要保持原来顺序的时候,特别特别好用。装饰一下就行,使用也非常方便


TreeList


TreeList实现了优化的快速插入和删除任何索引的列表。这个列表内部实现利用树结构,确保所有的插入和删除都是O(log n)。

    public static void main(String[] args) {
        List<String> list = new TreeList<>();
        list.add("fang");
        list.add("shi");
        list.add("shi");
        list.add("xiang");
        System.out.println(list); //[fang, shi, shi, xiang]
    }


相关文章
|
27天前
|
存储 安全 Java
【Java集合类面试二十五】、有哪些线程安全的List?
线程安全的List包括Vector、Collections.SynchronizedList和CopyOnWriteArrayList,其中CopyOnWriteArrayList通过复制底层数组实现写操作,提供了最优的线程安全性能。
|
27天前
|
Java
【Java集合类面试二十三】、List和Set有什么区别?
List和Set的主要区别在于List是一个有序且允许元素重复的集合,而Set是一个无序且元素不重复的集合。
|
18天前
|
Java
用JAVA架建List集合为树形结构的代码方法
这段代码定义了一个表示树形结构的 `Node` 类和一个用于构建树形结构的 `TreeController`。`Node` 类包含基本属性如 `id`、`pid`、`name` 和 `type`,以及子节点列表 `children`。`TreeController` 包含初始化节点列表并将其转换为树形结构的方法。通过过滤和分组操作实现树形结构的构建。详情可见:[代码示例链接1](http://www.zidongmutanji.com/zsjx/43551.html),[代码效果参考链接2](https://www.257342.com/sitemap/post.html)。
28 5
|
15天前
|
Java API 开发者
代码小妙招:用Java轻松获取List交集数据
在Java中获取两个 `List`的交集可以通过 `retainAll`方法和Java 8引入的流操作来实现。使用 `retainAll`方法更为直接,但会修改原始 `List`的内容。而使用流则提供了不修改原始 `List`、更为灵活的处理方式。开发者可以根据具体的需求和场景,选择最适合的方法来实现。了解和掌握这些方法,能够帮助开发者在实际开发中更高效地处理集合相关的问题。
13 1
|
25天前
|
存储 Java API
【Java高手必备】揭秘!如何优雅地对List进行排序?掌握这几种技巧,让你的代码瞬间高大上!
【8月更文挑战第23天】本文深入探讨了Java中对List集合进行排序的各种方法,包括使用Collections.sort()、自定义Comparator以及Java 8的Stream API。通过示例代码展示了不同情况下如何选择合适的方法:从简单的整数排序到自定义类对象的排序,再到利用Comparator指定特殊排序规则,最后介绍了Stream API在排序操作中的简洁应用。理解这些技术的区别与应用场景有助于提高编程效率。
19 4
|
24天前
|
消息中间件 Java Kafka
【Azure 事件中心】在微软云中国区 (Mooncake) 上实验以Apache Kafka协议方式发送/接受Event Hubs消息 (Java版)
【Azure 事件中心】在微软云中国区 (Mooncake) 上实验以Apache Kafka协议方式发送/接受Event Hubs消息 (Java版)
|
17天前
|
Java 前端开发 Apache
Apache Wicket与Spring MVC等Java Web框架大PK,究竟谁才是你的最佳拍档?点击揭秘!
【8月更文挑战第31天】在Java Web开发领域,众多框架各具特色。Apache Wicket以组件化开发和易用性脱颖而出,提高了代码的可维护性和可读性。相比之下,Spring MVC拥有强大的生态系统,但学习曲线较陡;JSF与Java EE紧密集成,但在性能和灵活性上略逊一筹;Struts2虽成熟,但在RESTful API支持上不足。选择框架时还需考虑社区支持和文档完善程度。希望本文能帮助开发者找到最适合自己的框架。
26 0
|
26天前
|
存储 Java 索引
|
Java
java中Set,Map,Stack一些简单用法
1 import java.util.Iterator; 2 import java.util.Stack; 3 import java.io.*; 4 import java.util.
626 0

推荐镜像

更多