java google guava 的 Multiset 使用总结

一、概述

Guava提供了一个新集合类型Multiset,它可以多次添加相等的元素,且和元素顺序无关。Multiset继承于JDK的Cllection接口,而不是Set接口。它和set最大的区别就是

它可以对相同元素做一个计数的功能,普通的 Set 就像这样 :[car, ship, bike],而 Multiset 会是这样 : [car x 2, ship x 6, bike x 3]Multiset有一个有用的功能,

就是跟踪每种对象的数量,所以你可以用来进行数字统计。每存放一个相同元素,那么该元素的count就加1。

譬如一个 List 里面有各种字符串,然后你要统计每个字符串在 List 里面出现的次数,这个用Multiset就能够快速实现。

1、举例说明

主要看运行结果:

java google guava 的 Multiset 使用总结

根据运行结果我们得到:

(1)它把把list放入HashMultiset中,就成了key还是list的属性,value就是重复数的一个计数。

(2)每添加一个相同元素,计数+1。

(3)可以添加和移除计数的值。

 2、Multiset主要方法介绍

  • add(E element) :向其中添加单个元素
  • add(E element,int occurrences) : 向其中添加指定个数的元素
  • count(Object element) : 返回给定参数元素的个数
  • remove(E element) : 移除一个元素,其count值 会响应减少
  • remove(E element,int occurrences): 移除相应个数的元素
  • elementSet() : 将不同的元素放入一个Set中
  • entrySet(): 类似与Map.entrySet 返回Set<Multiset.Entry>。包含的Entry支持使用getElement()和getCount()
  • setCount(E element ,int count): 设定某一个元素的重复次数
  • setCount(E element,int oldCount,int newCount): 将符合原有重复个数的元素修改为新的重复次数
  • retainAll(Collection c) : 保留出现在给定集合参数的所有的元素
  • removeAll(Collectionc) : 去除出现给给定集合参数的所有的元素

 3、常用的实现了Multiset 接口的类

1、HashMultiset: 元素存放于 HashMap

2、LinkedHashMultiset: 元素存放于 LinkedHashMap,即元素的排列顺序由第一次放入的顺序决定

3、TreeMultiset:元素被排序存放于TreeMap

4、EnumMultiset: 元素必须是 enum 类型

5、ImmutableMultiset: 不可修改的 Mutiset

4、Multiset与Map<E, Integer>区别

实际开发中我们也可以利用Map<E, Integer>来实现计数功能,但它和Multiset还是有很大区别的,首先Multiset也不是Map<E, Integer>类型的结构,区别如下:

1、Multiset中的元素出现的次数只能为正数,前面说了原因。如果E的出现次数为0,那么E将不出现在multiset中,是不能在elementSet()和entrySet()的视图中;

2、multiset.size()返回这个集合的大小,相当于在multiset中元素的出现的总数。如果想得到multiset中不同元素出现的总数,可以利用elementSet().size()来实现;

3、multiset.iterator()可以遍历multiset中的所有元素,所以iteration遍历的次数就等于multiset.size();

4、Multiset支持添加、删除元素,设置元素出现的次数;setCount(elem, 0)相当于移除elem的所有元素;

5、multiset.count(elem)方法中的elem如果没有出现在Multiset中,那么它的返回值永远都是0。

0

Java中便历Map的方法总结

java中的map遍历有多种方法,从最早的Iterator,到java5支持的foreach,再到java8 Lambda,让我们一起来看下具体的用法以及各自的优缺点

先初始化一个map:

keySet values

如果只需要map的key或者value,用map的keySet或values方法无疑是最方便的

keySet get(key)

如果需要同时获取key和value,可以先获取key,然后再通过map的get(key)获取value

需要说明的是,该方法不是最优选择,一般不推荐使用

entrySet

通过对map entrySet的遍历,也可以同时拿到key和value,一般情况下,性能上要优于上一种,这一种也是最常用的遍历方法

Iterator

对于上面的几种foreach都可以用Iterator代替,其实foreach在java5中才被支持,foreach的写法看起来更简洁

但Iterator也有其优势:在用foreach遍历map时,如果改变其大小,会报错,但如果只是删除元素,可以使用Iterator的remove方法删除元素

Lambda

java8提供了Lambda表达式支持,语法看起来更简洁,可以同时拿到key和value,不过,经测试,性能低于entrySet,所以更推荐用entrySet的方式

0

java8 stream forEachOrdered 和 forEach 的区别

 

这两个函数都是对集合的流,进行遍历操作,是属于内部迭代;传入一个Consumer的函数接口,下面通过案例,简单了解下:

先看第一段输出和第二段输出,使用的是stream的串行流,也就是程序是串行执行的,所有看到遍历的结果都是按照集合的元素放入的顺序。

看第三段和第四段输出,使用的parallelStream的并行流,也就是在程序内部迭代的时候,会并行处理。

第三段代码的forEachOrdered表示严格按照顺序取数据,第四段forEach在并行中,元素随机排列了。

由此可看出,在并行的程序中,如果对处理之后的数据,没有顺序的要求,使用forEach的效率,肯定是要更好的。

以上就是 java8 stream forEachOrdered 和 forEach 的区别。

 

 

0

Java8 stream list 转 map 方法总结

list转map在Java8中stream的应用

1.利用Collectors.toMap方法进行转换

其中第一个参数就是可以,第二个参数就是value的值。

2.收集对象实体本身

在开发过程中我们也需要有时候对自己的list中的实体按照其中的一个字段进行分组(比如 id ->List),这时候要设置map的value值是实体本身。

account -> account是一个返回本身的lambda表达式,其实还可以使用Function接口中的一个默认方法 Function.identity(),这个方法返回自身对象,更加简洁

重复key的情况

在list转为map时,作为key的值有可能重复,这时候流的处理会抛出个异常:Java.lang.IllegalStateException:Duplicate key。这时候就要在toMap方法中指定当key冲突时key的选择。(这里是选择第二个key覆盖第一个key)

用groupingBy 或者 partitioningBy进行分组

根据一个字段或者属性分组也可以直接用groupingBy方法,很方便。

partitioningBy可以理解为特殊的groupingBy,key值为true和false,当然此时方法中的参数为一个判断语句(用于判断的函数式接口)

 

 

0

Java Collections.emptyList() 方法的使用及注意事项

Java Collections.emptyList方法的使用及注意事项

一、emptyList()

作用:

返回一个空的List(使用前提是不会再对返回的list进行增加和删除操作);

好处:

1. new ArrayList()创建时有初始大小,占用内存,emptyList()不用创建一个新的对象,可以减少内存开销;
2. 方法返回一个emptyList()时,不会报空指针异常,如果直接返回Null,没有进行非空判断就会报空指针异常;

注意:此List与常用的List不同,它是Collections类里的静态内部类,在继承AbstractList后并没有实现add()、remove()等方法,所以返回的List不能进行增加和删除元素操作。

示例:

增删操作:

结果:

Java Collections.emptyList() 方法的使用及注意事项

如果需要对collections.emptyList()进行增删操作的话,就需要将collections.emptyList()转换成ArrayList()进行操作。

示例:

结果:

Java Collections.emptyList() 方法的使用及注意事项

0

Java数组和Set互相转换

数组转Set

Set转数组

 

0

如何求java集合的交集,并集,差集

如何求java集合的交集,并集,差集

 

0

Java 集合框架继承图

java集合继承关系图

面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。

数组虽然也可以存储对象,但长度是固定的;集合长度是可变的,数组中可以存储基本数据类型,集合只能存储对象。

集合类的特点:集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。

Java 集合框架继承图

上述类图中,实线边框的是Java实现类,比如ArrayList,LinkedList,HashMap等,折线边框的是抽象类,比如AbstractCollection,AbstractList,AbstractMap等,而点线边框的是接口,比如Collection,Iterator,List等。

0