Maven
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.0-jre</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.1.0</version>
</dependency>
Collections
1.反转指定列表中元素的顺序
public static void reverse(List<?> list)
2.随机排列集合
public static void shuffle(List<?> list)
3.交换指定位置的集合
public static void swap(List<?> list, int i, int j)
4.用指定的元素替换指定列表中的所有元素
public static <T> void fill(List<? super T> list, T obj)
5.获取最小值
public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll)
6.获取最大值
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)
7.用新值替换旧值
public static <T> boolean replaceAll(List<T> list, T oldVal, T newVal)
hutool
CollUtil
1.两个集合的并集
/**
* 两个集合的并集<br>
* 针对一个集合中存在多个相同元素的情况,计算两个集合中此元素的个数,保留最多的个数<br>
* 例如:集合1:[a, b, c, c, c],集合2:[a, b, c, c]<br>
* 结果:[a, b, c, c, c],此结果中只保留了三个c
*
* @param <T> 集合元素类型
* @param coll1 集合1
* @param coll2 集合2
* @return 并集的集合,返回 {@link ArrayList}
*/
public static <T> Collection<T> union(Collection<T> coll1, Collection<T> coll2) {
final ArrayList<T> list = new ArrayList<>();
if (isEmpty(coll1)) {
list.addAll(coll2);
} else if (isEmpty(coll2)) {
list.addAll(coll1);
} else {
final Map<T, Integer> map1 = countMap(coll1);
final Map<T, Integer> map2 = countMap(coll2);
final Set<T> elts = newHashSet(coll2);
elts.addAll(coll1);
int m;
for (T t : elts) {
m = Math.max(Convert.toInt(map1.get(t), 0), Convert.toInt(map2.get(t), 0));
for (int i = 0; i < m; i++) {
list.add(t);
}
}
}
return list;
}
2.两个集合的交集
/**
* 两个集合的交集<br>
* 针对一个集合中存在多个相同元素的情况,计算两个集合中此元素的个数,保留最少的个数<br>
* 例如:集合1:[a, b, c, c, c],集合2:[a, b, c, c]<br>
* 结果:[a, b, c, c],此结果中只保留了两个c
*
* @param <T> 集合元素类型
* @param coll1 集合1
* @param coll2 集合2
* @return 交集的集合,返回 {@link ArrayList}
*/
public static <T> Collection<T> intersection(Collection<T> coll1, Collection<T> coll2) {
final ArrayList<T> list = new ArrayList<>();
if (isNotEmpty(coll1) && isNotEmpty(coll2)) {
final Map<T, Integer> map1 = countMap(coll1);
final Map<T, Integer> map2 = countMap(coll2);
final Set<T> elts = newHashSet(coll2);
int m;
for (T t : elts) {
m = Math.min(Convert.toInt(map1.get(t), 0), Convert.toInt(map2.get(t), 0));
for (int i = 0; i < m; i++) {
list.add(t);
}
}
}
return list;
}
3.两个集合的差集
/**
* 两个集合的差集<br>
* 针对一个集合中存在多个相同元素的情况,计算两个集合中此元素的个数,保留两个集合中此元素个数差的个数<br>
* 例如:集合1:[a, b, c, c, c],集合2:[a, b, c, c]<br>
* 结果:[c],此结果中只保留了一个<br>
* 任意一个集合为空,返回另一个集合<br>
* 两个集合无差集则返回空集合
*
* @param <T> 集合元素类型
* @param coll1 集合1
* @param coll2 集合2
* @return 差集的集合,返回 {@link ArrayList}
*/
public static <T> Collection<T> disjunction(Collection<T> coll1, Collection<T> coll2) {
if (isEmpty(coll1)) {
return coll2;
}
if (isEmpty(coll2)) {
return coll1;
}
final ArrayList<T> result = new ArrayList<>();
final Map<T, Integer> map1 = countMap(coll1);
final Map<T, Integer> map2 = countMap(coll2);
final Set<T> elts = newHashSet(coll2);
elts.addAll(coll1);
int m;
for (T t : elts) {
m = Math.abs(Convert.toInt(map1.get(t), 0) - Convert.toInt(map2.get(t), 0));
for (int i = 0; i < m; i++) {
result.add(t);
}
}
return result;
}
4.判断两个集合是否至少有一个共同的元素
/**
* 其中一个集合在另一个集合中是否至少包含一个元素,即是两个集合是否至少有一个共同的元素
*
* @param coll1 集合1
* @param coll2 集合2
* @return 其中一个集合在另一个集合中是否至少包含一个元素
* @see #intersection
* @since 2.1
*/
public static boolean containsAny(Collection<?> coll1, Collection<?> coll2) {
if (isEmpty(coll1) || isEmpty(coll2)) {
return false;
}
if (coll1.size() < coll2.size()) {
for (Object object : coll1) {
if (coll2.contains(object)) {
return true;
}
}
} else {
for (Object object : coll2) {
if (coll1.contains(object)) {
return true;
}
}
}
return false;
}
5.判断集合2是否为集合1的子集
/**
* 集合1中是否包含集合2中所有的元素,即集合2是否为集合1的子集
*
* @param coll1 集合1
* @param coll2 集合2
* @return 集合1中是否包含集合2中所有的元素
* @since 4.5.12
*/
public static boolean containsAll(Collection<?> coll1, Collection<?> coll2) {
if (isEmpty(coll1) || isEmpty(coll2) || coll1.size() < coll2.size()) {
return false;
}
for (Object object : coll2) {
if (false == coll1.contains(object)) {
return false;
}
}
return true;
}
6.根据集合返回一个元素计数的 Map
/**
* 根据集合返回一个元素计数的 {@link Map}<br>
* 所谓元素计数就是假如这个集合中某个元素出现了n次,那将这个元素做为key,n做为value<br>
* 例如:[a,b,c,c,c] 得到:<br>
* a: 1<br>
* b: 1<br>
* c: 3<br>
*
* @param <T> 集合元素类型
* @param collection 集合
* @return {@link Map}
* @see IterUtil#countMap(Iterable)
*/
public static <T> Map<T, Integer> countMap(Iterable<T> collection) {
return IterUtil.countMap(collection);
}
7.以 conjunction 为分隔符将集合转换为字符串
/**
* 以 conjunction 为分隔符将集合转换为字符串<br>
* 如果集合元素为数组、{@link Iterable}或{@link Iterator},则递归组合其为字符串
*
* @param <T> 集合元素类型
* @param iterable {@link Iterable}
* @param conjunction 分隔符
* @return 连接后的字符串
* @see IterUtil#join(Iterable, CharSequence)
*/
public static <T> String join(Iterable<T> iterable, CharSequence conjunction) {
return IterUtil.join(iterable, conjunction);
}
实例:
@Test
public void test() {
List<List<Integer>> list = CollUtil.newArrayList(Lists.newArrayList(1,2,3),Lists.newArrayList(4,5,6));
String join = CollUtil.join(list, ",");
System.out.println("join = " + join);
}
结果:
join = 1,2,3,4,5,6
8.截取集合的部分
/**
* 截取集合的部分
*
* @param <T> 集合元素类型
* @param list 被截取的数组
* @param start 开始位置(包含)
* @param end 结束位置(不包含)
* @param step 步进
* @return 截取后的数组,当开始位置超过最大时,返回空的List
* @since 4.0.6
*/
public static <T> List<T> sub(List<T> list, int start, int end, int step) {
if (list == null) {
return null;
}
if (list.isEmpty()) {
return new ArrayList<>(0);
}
final int size = list.size();
if (start < 0) {
start += size;
}
if (end < 0) {
end += size;
}
if (start == size) {
return new ArrayList<>(0);
}
if (start > end) {
int tmp = start;
start = end;
end = tmp;
}
if (end > size) {
if (start >= size) {
return new ArrayList<>(0);
}
end = size;
}
if (step <= 1) {
return list.subList(start, end);
}
final List<T> result = new ArrayList<>();
for (int i = start; i < end; i += step) {
result.add(list.get(i));
}
return result;
}
实例:
@Test
public void test1() {
List<Integer> list = CollUtil.newArrayList(1, 2, 3, 4, 5, 6, 7,8,9,10);
List<Integer> result = CollUtil.sub(list, 0, 10, 2);
System.out.println("result = " + result);
}
结果:
result = [1, 3, 5, 7, 9]
9.对集合按照指定长度分段,每一个段为单独的集合,返回这个集合的列表
/**
* 对集合按照指定长度分段,每一个段为单独的集合,返回这个集合的列表
*
* @param <T> 集合元素类型
* @param collection 集合
* @param size 每个段的长度
* @return 分段列表
*/
public static <T> List<List<T>> split(Collection<T> collection, int size) {
final List<List<T>> result = new ArrayList<>();
ArrayList<T> subList = new ArrayList<>(size);
for (T t : collection) {
if (subList.size() >= size) {
result.add(subList);
subList = new ArrayList<>(size);
}
subList.add(t);
}
result.add(subList);
return result;
}
实例:
@Test
public void test2() {
List<Integer> list = CollUtil.newArrayList(1, 2, 3, 4, 5, 6, 7,8,9,10);
List<List<Integer>> result = CollUtil.split(list, 2);
System.out.println("result = " + result);
}
结果:
result = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
10.去除空元素,此方法直接修改原集合
/**
* 去除{@code null} 元素,此方法直接修改原集合
*
* @param <T> 集合类型
* @param <E> 集合元素类型
* @param collection 集合
* @return 处理后的集合
* @since 3.2.2
*/
public static <T extends Collection<E>, E> T removeNull(T collection) {
return filter(collection, Objects::nonNull);
}
/**
* 去除{@code null}或者"" 元素,此方法直接修改原集合
*
* @param <T> 集合类型
* @param <E> 集合元素类型
* @param collection 集合
* @return 处理后的集合
* @since 3.2.2
*/
public static <T extends Collection<E>, E extends CharSequence> T removeEmpty(T collection) {
return filter(collection, StrUtil::isNotEmpty);
}
/**
* 去除{@code null}或者""或者空白字符串 元素,此方法直接修改原集合
*
* @param <T> 集合类型
* @param <E> 集合元素类型
* @param collection 集合
* @return 处理后的集合
* @since 3.2.2
*/
public static <T extends Collection<E>, E extends CharSequence> T removeBlank(T collection) {
return filter(collection, StrUtil::isNotBlank);
}
11.获取给定Bean列表中指定字段名对应字段值的列表
/**
* 获取给定Bean列表中指定字段名对应字段值的列表<br>
* 列表元素支持Bean与Map
*
* @param collection Bean集合或Map集合
* @param fieldName 字段名或map的键
* @return 字段值列表
* @since 3.1.0
*/
public static List<Object> getFieldValues(Iterable<?> collection, final String fieldName) {
return getFieldValues(collection, fieldName, false);
}
实例:
@Test
public void test3() {
List<Map<String, String>> list = new ArrayList<>();
Map<String, String> map = new HashMap<>();
map.put("name", "skh");
map.put("address", "西湖区");
Map<String, String> map1 = new HashMap<>();
map1.put("name", "csn");
map1.put("address", "西湖区");
list.add(map);
list.add(map1);
List<String> result = CollUtil.getFieldValues(list, "name", String.class);
System.out.println("result = " + result);
}
结果:
result = [skh, csn]
12.映射键值
/**
* 映射键值(参考Python的zip()函数)<br>
* 例如:<br>
* keys = a,b,c,d<br>
* values = 1,2,3,4<br>
* delimiter = , 则得到的Map是 {a=1, b=2, c=3, d=4}<br>
* 如果两个数组长度不同,则只对应最短部分
*
* @param keys 键列表
* @param values 值列表
* @param delimiter 分隔符
* @param isOrder 是否有序
* @return Map
* @since 3.0.4
*/
public static Map<String, String> zip(String keys, String values, String delimiter, boolean isOrder) {
return ArrayUtil.zip(StrUtil.split(keys, delimiter), StrUtil.split(values, delimiter), isOrder);
}
13.行转列,合并相同的键,值合并为列表
/**
* 行转列,合并相同的键,值合并为列表<br>
* 将Map列表中相同key的值组成列表做为Map的value<br>
* 是{@link #toMapList(Map)}的逆方法<br>
* 比如传入数据:
*
* <pre>
* [
* {a: 1, b: 1, c: 1}
* {a: 2, b: 2}
* {a: 3, b: 3}
* {a: 4}
* ]
* </pre>
* <p>
* 结果是:
*
* <pre>
* {
* a: [1,2,3,4]
* b: [1,2,3,]
* c: [1]
* }
* </pre>
*
* @param <K> 键类型
* @param <V> 值类型
* @param mapList Map列表
* @return Map
* @see MapUtil#toListMap(Iterable)
*/
public static <K, V> Map<K, List<V>> toListMap(Iterable<? extends Map<K, V>> mapList) {
return MapUtil.toListMap(mapList);
}
14.列转行。将Map中值列表分别按照其位置与key组成新的map
/**
* 列转行。将Map中值列表分别按照其位置与key组成新的map。<br>
* 是{@link #toListMap(Iterable)}的逆方法<br>
* 比如传入数据:
*
* <pre>
* {
* a: [1,2,3,4]
* b: [1,2,3,]
* c: [1]
* }
* </pre>
* <p>
* 结果是:
*
* <pre>
* [
* {a: 1, b: 1, c: 1}
* {a: 2, b: 2}
* {a: 3, b: 3}
* {a: 4}
* ]
* </pre>
*
* @param <K> 键类型
* @param <V> 值类型
* @param listMap 列表Map
* @return Map列表
* @see MapUtil#toMapList(Map)
*/
public static <K, V> List<Map<K, V>> toMapList(Map<K, ? extends Iterable<V>> listMap) {
return MapUtil.toMapList(listMap);
}
15.根据元素的指定字段名分组,非Bean都放在第一个分组中
/**
* 根据元素的指定字段名分组,非Bean都放在第一个分组中
*
* @param <T> 元素类型
* @param collection 集合
* @param fieldName 元素Bean中的字段名,非Bean都放在第一个分组中
* @return 分组列表
*/
public static <T> List<List<T>> groupByField(Collection<T> collection, final String fieldName) {
return group(collection, new Hash<T>() {
private final List<Object> fieldNameList = new ArrayList<>();
@Override
public int hash(T t) {
if (null == t || false == BeanUtil.isBean(t.getClass())) {
// 非Bean放在同一子分组中
return 0;
}
final Object value = ReflectUtil.getFieldValue(t, fieldName);
int hash = fieldNameList.indexOf(value);
if (hash < 0) {
fieldNameList.add(value);
return fieldNameList.size() - 1;
} else {
return hash;
}
}
});
}
实例:
@Test
public void test4() {
List<UserDO> list = new ArrayList<>();
UserDO userDO1 = new UserDO(1, "skh");
UserDO userDO2 = new UserDO(2, "csn");
UserDO userDO3 = new UserDO(3 ,"skh");
list.add(userDO1);
list.add(userDO2);
list.add(userDO3);
List<List<UserDO>> result = CollUtil.groupByField(list, "name");
System.out.println("result = " + result);
}
结果:
result = [[UserDO(id=1, name=skh), UserDO(id=3, name=skh)], [UserDO(id=2, name=csn)]]
MapUtil
1.将键值对转换为二维数组
/**
* 将键值对转换为二维数组,第一维是key,第二纬是value
*
* @param map map
* @return 数组
* @since 4.1.9
*/
public static Object[][] toObjectArray(Map<?, ?> map) {
if (map == null) {
return null;
}
final Object[][] result = new Object[map.size()][2];
if (map.isEmpty()) {
return result;
}
int index = 0;
for (Entry<?, ?> entry : map.entrySet()) {
result[index][0] = entry.getKey();
result[index][1] = entry.getValue();
index++;
}
return result;
}
2.过滤
/**
* 过滤<br>
* 过滤过程通过传入的Editor实现来返回需要的元素内容,这个Filter实现可以实现以下功能:
*
* <pre>
* 1、过滤出需要的对象,如果返回null表示这个元素对象抛弃
* </pre>
*
* @param <K> Key类型
* @param <V> Value类型
* @param map Map
* @param filter 编辑器接口
* @return 过滤后的Map
* @since 3.1.0
*/
public static <K, V> Map<K, V> filter(Map<K, V> map, Filter<Entry<K, V>> filter) {
if (null == map || null == filter) {
return map;
}
final Map<K, V> map2 = ObjectUtil.clone(map);
if (isEmpty(map2)) {
return map2;
}
map2.clear();
for (Entry<K, V> entry : map.entrySet()) {
if (filter.accept(entry)) {
map2.put(entry.getKey(), entry.getValue());
}
}
return map2;
}
/**
* 过滤Map保留指定键值对,如果键不存在跳过
*
* @param <K> Key类型
* @param <V> Value类型
* @param map 原始Map
* @param keys 键列表
* @return Map 结果,结果的Map类型与原Map保持一致
* @since 4.0.10
*/
@SuppressWarnings("unchecked")
public static <K, V> Map<K, V> filter(Map<K, V> map, K... keys) {
final Map<K, V> map2 = ObjectUtil.clone(map);
if (isEmpty(map2)) {
return map2;
}
map2.clear();
for (K key : keys) {
if (map.containsKey(key)) {
map2.put(key, map.get(key));
}
}
return map2;
}
3.Map的键和值互换
/**
* Map的键和值互换
*
* @param <T> 键和值类型
* @param map Map对象,键值类型必须一致
* @return 互换后的Map
* @since 3.2.2
*/
public static <T> Map<T, T> reverse(Map<T, T> map) {
return filter(map, (Editor<Entry<T, T>>) t -> new Entry<T, T>() {
@Override
public T getKey() {
return t.getValue();
}
@Override
public T getValue() {
return t.getKey();
}
@Override
public T setValue(T value) {
throw new UnsupportedOperationException("Unsupported setValue method !");
}
});
}
4.获取Map指定key的值,并转换为指定类型
/**
* 获取Map指定key的值,并转换为指定类型
*
* @param <T> 目标值类型
* @param map Map
* @param key 键
* @param type 值类型
* @return 值
* @since 4.0.6
*/
public static <T> T get(Map<?, ?> map, Object key, Class<T> type) {
return null == map ? null : Convert.convert(type, map.get(key));
}
5.重命名键
/**
* 重命名键<br>
* 实现方式为一处然后重新put,当旧的key不存在直接返回<br>
* 当新的key存在,抛出{@link IllegalArgumentException} 异常
*
* @param <K> key的类型
* @param <V> value的类型
* @param map Map
* @param oldKey 原键
* @param newKey 新键
* @return map
* @throws IllegalArgumentException 新key存在抛出此异常
* @since 4.5.16
*/
public static <K, V> Map<K, V> renameKey(Map<K, V> map, K oldKey, K newKey) {
if (isNotEmpty(map) && map.containsKey(oldKey)) {
if (map.containsKey(newKey)) {
throw new IllegalArgumentException(StrUtil.format("The key '{}' exist !", newKey));
}
map.put(newKey, map.remove(oldKey));
}
return map;
}
Guava
Multimap->Map<String,List>
@Test
public void test6() {
//Multimap multimap = ArrayListMultimap.create(); //arraylist
Multimap multimap = HashMultimap.create(); //hashmap
multimap.put("name", "skh");
multimap.put("name", "csn");
multimap.put("name", "Bob");
multimap.put("age", 1);
multimap.put("age", 2);
multimap.put("age", 3);
System.out.println("result = " + multimap);
}
结果:
result = {name=[Bob, skh, csn], age=[1, 2, 3]}
Multiset:一个名叫set的计数器
Multiset
的作用就是对重复元素计数…
内部实现使用HashMap来保存key->count
的一个映射关系.
@Test
public void test7() {
Multiset<String> s = HashMultiset.create();
s.add("1");
s.add("1");
s.add("2");
s.add("2");
s.add("3");
//获取set里的元素(无重复)
Set<String> strings = s.elementSet();
System.out.println("strings = " + strings);
//统计元素出现的次数
int i = s.count("1");
System.out.println("i = " + i);
}
结果:
strings = [1, 2, 3]
i = 2
BiMap -> value也不可以重复的双向Map
它必须保证key和value都没有重复值.因为他支持根据value获取key,即将HashMap的key和value进行调换.
这个类适合用在key和value都唯一,且经常会出现根据value来获取key的情况.
@Test
public void test8() {
BiMap<String, String> m = HashBiMap.create();
m.put("skh", "111");
//通过key获取value
String value = m.get("skh");
System.out.println("value = " + value);
//通过value获取key
String key = m.inverse().get("111");
System.out.println("key = " + key);
}
结果:
value = 111
key = skh
Table -> Map<String,Map<String,Object>> 多个索引映射一个结果
@Test
public void test9() {
//多个索引对应一个结果,比如这里的rowKey和columnKey都能查找到指定的value
Table<String,String,Integer> table = HashBasedTable.create();
table.put("张三","语文",93);
table.put("张三","数学",100);
table.put("张三","英语",99);
table.put("李四","语文",98);
table.put("李四","数学",90);
table.put("李四","英语",89);
System.out.println(table.row("李四")); // {语文=98, 数学=90, 英语=89}
System.out.println(table.get("张三","英语")); // 99
System.out.println(table.get("张三","体育")); // null
Map<String, Integer> columnMap = table.column("语文"); //{张三=93, 李四=98}
}
ComparisonChain -> 功能强大且好看的多字段比较方法
在面对多个字段排序比较的场景,一般我们的代码都会比较难看,比如对下面这个类:
private static class Student {
int id;
String name;
int age;
}
首先比较id,id相等比较name,name相等比较age,这是一种很常见的多字段比较策略.那么我们给Student
类加上Comparable
的实现.
// 为了简洁起见,没有写外部类代码,只贴了重写的comparTo方法.
@Override
public int compareTo(Object o) {
Student s = (Student) o;
int idResult = s.id - this.id;
int nameResult = s.name.compareTo(this.name);
int ageResult = s.age - this.age;
return idResult != 0 ? idResult : nameResult != 0 ? nameResult : ageResult;
}
最后那一串?:?:
是不是看的眼睛疼,当然你可以选择三重if-else,我觉得也没好到哪里去.
但是可以使用ComparisonChain
,这名字一看就是比较链,非常适合我们的场景.改写如下:
@Override
public int compareTo(Object o) {
Student s = (Student) o;
return ComparisonChain.start().compare(s.id, this.id).compare(s.name, this.name).compare(s.age, this.age).
result();
}
找出2个Map的不同之处,以Map形式返回
@Test
public void test10() {
HashMap<String, String> left = new HashMap<>();
left.put("name", "skh");
left.put("addr", "西湖区");
left.put("age", "25");
left.put("sex", "男");
HashMap<String, String> right = new HashMap<>();
right.put("name", "csn");
right.put("addr", "西湖区");
right.put("age", "24");
right.put("birth", "1993");
MapDifference<String, String> difference = Maps.difference(left, right);
Map<String, String> leftMap = difference.entriesOnlyOnLeft();
System.out.println("leftMap = " + leftMap);
Map<String, String> rightMap = difference.entriesOnlyOnRight();
System.out.println("rightMap = " + rightMap);
Map<String, MapDifference.ValueDifference<String>> differenceMap = difference.entriesDiffering();
System.out.println("differenceMap = " + differenceMap);
Map<String, String> commonMap = difference.entriesInCommon();
System.out.println("commonMap = " + commonMap);
}
结果:
leftMap = {sex=男}
rightMap = {birth=1993}
differenceMap = {name=(skh, csn), age=(25, 24)}
commonMap = {addr=西湖区}
求笛卡尔积
@Test
public void test11() {
Set<Integer> set1 = Sets.newHashSet(1, 2, 3);
Set<Integer> set2 = Sets.newHashSet(4,5,6);
//Set<Integer> set3 = Sets.newHashSet(7,8,9);
Set<List<Integer>> result = Sets.cartesianProduct(set1, set2);
System.out.println("result = " + result);
}
结果:
result = [[1, 4], [1, 5], [1, 6], [2, 4], [2, 5], [2, 6], [3, 4], [3, 5], [3, 6]]
求集合的所有子集,按指定长度分割
@Test
public void test12() {
Set<Integer> set1 = Sets.newHashSet(1, 2, 3);
Set<Set<Integer>> result = Sets.combinations(set1, 2);
for (Set<Integer> set : result) {
System.out.println("set = " + set);
}
System.out.println("result = " + result);
}
结果:
set = [1, 2]
set = [1, 3]
set = [2, 3]
result = Sets.combinations([1, 2, 3], 2)
求集合的所有子集
@Test
public void test13() {
Set<Integer> set1 = Sets.newHashSet(1, 2, 3);
Set<Set<Integer>> result = Sets.powerSet(set1);
for (Set<Integer> set : result) {
System.out.println("set = " + set);
}
System.out.println("result = " + result);
}
结果:
set = []
set = [1]
set = [2]
set = [1, 2]
set = [3]
set = [1, 3]
set = [2, 3]
set = [1, 2, 3]
result = powerSet({1=0, 2=1, 3=2})
求差集
@Test
public void test14() {
Set<Integer> set1 = Sets.newHashSet(1, 2, 3,5,6);
Set<Integer> set2 = Sets.newHashSet(1, 2, 4);
Sets.SetView<Integer> result = Sets.difference(set1, set2); //返回set1中不存在的数据,会忽略set2中的元素
result.forEach(i -> System.out.println("i = " + i));
System.out.println("result = " + result);
}
结果:
i = 3
i = 5
i = 6
result = [3, 5, 6]
求交集
@Test
public void test15() {
Set<Integer> set1 = Sets.newHashSet(1, 2, 3,5,6);
Set<Integer> set2 = Sets.newHashSet(1, 2, 4);
//交集
Sets.SetView<Integer> result = Sets.intersection(set1, set2);
result.forEach(i -> System.out.println("i = " + i));
System.out.println("result = " + result);
}
结果:
i = 1
i = 2
result = [1, 2]
求并集
@Test
public void test16() {
Set<Integer> set1 = Sets.newHashSet(1, 2, 3,5,6);
Set<Integer> set2 = Sets.newHashSet(1, 2, 4);
//求并集
Sets.SetView<Integer> result = Sets.union(set1, set2);
result.forEach(i -> System.out.println("i = " + i));
System.out.println("result = " + result);
}
结果:
i = 1
i = 2
i = 3
i = 5
i = 6
i = 4
result = [1, 2, 3, 5, 6, 4]