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

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

Map工具类:MapUtils


这里汇聚了一些操作Map的方法,介绍一些觉得比较实用的方法:

  • emptyIfNull
    之前我们经常会这么写(不返回null的Map):
 if (map != null) {
            return Collections.emptyMap();
        }


现在可以直接这么来了:

return MapUtils.emptyIfNull(map);


  • fixedSizeMap、fixedSizeSortedMap


IterableMap<String, String> itMap = MapUtils.fixedSizeMap(map);


可以一键吧一个Map定长掉,放置一些误操作


  • invertMap
    对调key和value的值
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("key1", "value1");
        map.put("key2", "value2");
        map.put("key3", "value3");
        //fanzhuan反转  对调key和value
        Map<String, String> invertMap = MapUtils.invertMap(map);
        System.out.println(map); //{key1=value1, key2=value2, key3=value3}
        System.out.println(invertMap); //{value2=key2, value1=key1, value3=key3}
    }


  • iterableMap
    构建一个iterableMap,然后方便遍历、删除等等
    之前我们需要遍历删除Map中元素,需要



// 然后在根据key的迭代器去删除
map.entrySet().iterator();


现在方便了


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


  • populateMap
    能很方便向Map里面放值,并且支持定制化key和value,还是挺好用的


    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("key1", "value1");
        //序列化 根据提供的values,按照后面规则把key都生成出来然后直接放进去
        MapUtils.populateMap(map, Arrays.asList("a", "b", "c"), e -> "key-" + e);
        System.out.println(map); //{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(map, Arrays.asList("a", "b", "c"), e -> e, e -> "value-" + e); //java.util.ConcurrentModificationException
        System.out.println(map); //{key1=value1, key-a=a, a=value-a, b=value-b, c=value-c, key-c=c, key-b=b}
    }


同时该方法也提供了对MutiMap的支持


  • synchronizedMap、unmodifiableMap


  • toProperties:可以有非常简便的转化


    public static void main(String[] args) {
        Map<String, String> map = new HashMap<>();
        map.put("key1", "value1");
        map.put("key2", "value2");
        map.put("key3", "value2");
        Properties properties = MapUtils.toProperties(map);
        System.out.println(properties); //{key3=value2, key2=value2, key1=value1}
    }


SetUtils

difference:找到两个set之间的不同元素

返回的是第一个set里有的,但是第二个set里没有的元素们


    public static void main(String[] args) {
        Set<String> set1 = new HashSet<String>(){{
            add("a");
            add("b");
            add("c");
        }};
        Set<String> set2 = new HashSet<String>(){{
            add("c");
            add("d");
            add("e");
        }};
        SetUtils.SetView<String> difference = SetUtils.difference(set1, set2);
        System.out.println(difference); //[a,b]
        Set<String> strings = difference.toSet();
        System.out.println(strings); //[a,b]
    }


disjunction:和上面方法类似,但是属于加强版


会返回第一个set和第二个有差异的所有元素们


    public static void main(String[] args) {
        Set<String> set1 = new HashSet<String>(){{
            add("a");
            add("b");
            add("c");
        }};
        Set<String> set2 = new HashSet<String>(){{
            add("c");
            add("d");
            add("e");
        }};
        SetUtils.SetView<String> difference = SetUtils.disjunction(set1, set2);
        System.out.println(difference); //[a, b, d, e]
        Set<String> strings = difference.toSet();
        System.out.println(strings); //[a, b, d, e]
    }


emptyIfNull:见上MapUtils类似方法


newIdentityHashSet:可以实例化出一个newIdentityHashSet


至于它和HashSet的区别在哪里?若需要请参考我的博文:

【小家java】Java中IdentityHashMap使用详解—允许key重复(阐述和HashMap的区别)

他们的区别和HashMap的区别是一样的,请参阅


isEqualSet:


两个set里面的元素是否都一样(长度一样、元素一样),有时候判断还是非常有用的


union:合并两个set,生成一个新的set


    public static void main(String[] args) {
        Set<String> set1 = new HashSet<String>(){{
            add("a");
            add("b");
            add("c");
        }};
        Set<String> set2 = new HashSet<String>(){{
            add("c");
            add("d");
            add("e");
        }};
        SetUtils.SetView<String> union = SetUtils.union(set1, set2);
        System.out.println(union); //[a, b, c, d, e]
    }


类似于addAll的效果,但是它的好处是生成了一个新的set,对原来的set没有污染。


ListUtils


emptyIfNull:同上


defaultIfNull:可以在为null的时候,自己给个默认值返回


fixedSizeList:不解释


hashCodeForList:给List吧它的HashCode计算出来


intersection:取交集,生成一个新的List


    public static void main(String[] args) {
        List<String> list1 = new ArrayList<String>(){{
            add("a");
            add("b");
            add("c");
        }};
        List<String> list2 = new ArrayList<String>(){{
            add("c");
            add("d");
            add("e");
        }};
        //取出交集 并且返回一个新的List
        List<String> intersection = ListUtils.intersection(list1, list2);
        System.out.println(intersection); //[c]
        //这个方法也能取出交集的效果 但是会直接改变list1里面的元素  list2不变
        list1.retainAll(list2);
        System.out.println(list1); // [c]
        System.out.println(list2); //[c, d, e]
    }


partition:切割 把一个大的List切割成多个List 非常好用


常用场景:有10000个id需要批量查询,我们可以切割一下,200个发一次请求去查询一次,还可以开多个线程,用闭锁去弄


    public static void main(String[] args) {
        List<String> list1 = new ArrayList<String>(){{
            add("a");
            add("b");
            add("c");
            add("a");
            add("b");
            add("c");
            add("a");
            add("b");
            add("c");
        }};
        List<List<String>> partition = ListUtils.partition(list1, 4);
        System.out.println(partition); //[[a, b, c, a], [b, c, a, b], [c]]
    }


subtract:相当于做减法,用第一个List除去第二个list里含有的元素 ,然后生成一个新的list


    public static void main(String[] args) {
        List<String> list1 = new ArrayList<String>(){{
            add("a");
            add("b");
            add("c");
        }};
        List<String> list2 = new ArrayList<String>(){{
            add("c");
            add("d");
            add("e");
        }};
        //取出交集 并且返回一个新的List
        List<String> subtract = ListUtils.subtract(list1, list2);
        System.out.println(subtract); //[a,b]
    }

sum:把两个List的元素相加起来 注意:相同的元素不会加两次 生成一个新的List


    public static void main(String[] args) {
        List<String> list1 = new ArrayList<String>(){{
            add("a");
            add("b");
            add("c");
        }};
        List<String> list2 = new ArrayList<String>(){{
            add("c");
            add("c");
            add("c");
            add("d");
            add("e");
        }};
        //取出交集 并且返回一个新的List
        List<String> sumlist = ListUtils.sum(list1, list2);
        System.out.println(sumlist); //[a, b, c, d, e]
    }


此方法注意了,有相加的功能和去重的功能,很多场景还是很好用的


union:这个和sum方法不一样,它不带去重的功能。内部调用的addAll方法,但是生成一个新的List


例子:略

关于springframework的CollectionUtils


若你在上面没有找到操作集合的相关方法,可议参照Spring提供的这个工具类。API截图如下,就不详细分析了


image.png


总结


工欲善其事必先利其器,磨刀不误砍柴工。


希望整理的一些常用工具类、工具方法能够帮助到大家。

相关文章
|
3月前
|
存储 缓存 JavaScript
Set和Map有什么区别?
Set和Map有什么区别?
271 1
|
4月前
|
存储 JavaScript 前端开发
for...of循环在遍历Set和Map时的注意事项有哪些?
for...of循环在遍历Set和Map时的注意事项有哪些?
266 121
|
4月前
|
存储 C++ 容器
unordered_set、unordered_multiset、unordered_map、unordered_multimap的介绍及使用
unordered_set是不按特定顺序存储键值的关联式容器,其允许通过键值快速的索引到对应的元素。在unordered_set中,元素的值同时也是唯一地标识它的key。在内部,unordered_set中的元素没有按照任何特定的顺序排序,为了能在常数范围内找到指定的key,unordered_set将相同哈希值的键值放在相同的桶中。unordered_set容器通过key访问单个元素要比set快,但它通常在遍历元素子集的范围迭代方面效率较低。它的迭代器至少是前向迭代器。前向迭代器的特性。
189 0
|
4月前
|
编译器 C++ 容器
用一棵红黑树同时封装出map和set
再完成上面的代码后,我们的底层代码已经完成了,这时候已经是一个底层STL的红黑树了,已经已符合库里面的要求了,这时候我们是需要给他穿上对应的“衣服”,比如穿上set的“衣服”,那么这个穿上set的“衣服”,那么他就符合库里面set的要求了,同样map一样,这时候我们就需要实现set与map了。因此,上层容器map需要向底层红黑树提供一个仿函数,用于获取T当中的键值Key,这样一来,当底层红黑树当中需要比较两个结点的键值时,就可以通过这个仿函数来获取T当中的键值了。我们就可以使用仿函数了。
50 0
|
4月前
|
存储 编译器 容器
set、map、multiset、multimap的介绍及使用以及区别,注意事项
set是按照一定次序存储元素的容器,使用set的迭代器遍历set中的元素,可以得到有序序列。set当中存储元素的value都是唯一的,不可以重复,因此可以使用set进行去重。set默认是升序的,但是其内部默认不是按照大于比较,而是按照小于比较。set中的元素不能被修改,因为set在底层是用二叉搜索树来实现的,若是对二叉搜索树当中某个结点的值进行了修改,那么这棵树将不再是二叉搜索树。
202 0
|
7月前
|
人工智能 Java
Java 中数组Array和列表List的转换
本文介绍了数组与列表之间的相互转换方法,主要包括三部分:1)使用`Collections.addAll()`方法将数组转为列表,适用于引用类型,效率较高;2)通过`new ArrayList&lt;&gt;()`构造器结合`Arrays.asList()`实现类似功能;3)利用JDK8的`Stream`流式计算,支持基本数据类型数组的转换。此外,还详细讲解了列表转数组的方法,如借助`Stream`实现不同类型数组间的转换,并附带代码示例与执行结果,帮助读者深入理解两种数据结构的互转技巧。
377 1
Java 中数组Array和列表List的转换
|
7月前
|
编译器 C++ 容器
【c++丨STL】基于红黑树模拟实现set和map(附源码)
本文基于红黑树的实现,模拟了STL中的`set`和`map`容器。通过封装同一棵红黑树并进行适配修改,实现了两种容器的功能。主要步骤包括:1) 修改红黑树节点结构以支持不同数据类型;2) 使用仿函数适配键值比较逻辑;3) 实现双向迭代器支持遍历操作;4) 封装`insert`、`find`等接口,并为`map`实现`operator[]`。最终,通过测试代码验证了功能的正确性。此实现减少了代码冗余,展示了模板与仿函数的强大灵活性。
184 2
|
8月前
|
编译器 容器
哈希表模拟封装unordered_map和unordered_set
哈希表模拟封装unordered_map和unordered_set
|
8月前
|
编译器 测试技术 计算机视觉
红黑树模拟封装map和set
红黑树模拟封装map和set

热门文章

最新文章

推荐镜像

更多