上篇文章讲了EnumMap的实现,本篇文章按照惯例,介绍一下存储枚举类型集合Set类——EnumSet。但是跟之前HashSet和HashMap、TreeSet和TreeMap的关系不同,EnumSet不是依靠EnumMap实现的,甚至可以讲,实现方式跟EnumMap完全没有关系。另外和HashSet、TreeSet不同的是,EnumSet是抽象类,而HashSet、TreeSet是非抽象的。EnumMap的继承关系如下:
EnumSet继承了AbstractSet抽象类,表名EnumSet是支持基础的Set操作的,其它的方法都定义在EnumSet类中。
1. 调用示例
EnumSet是抽象类,所以不能通过构造函数构造EnumSet对象。在Java API中EnumSet抽象类有两个实现,分别是RegularEnumSet和JumboEnumSet。EnumSet中提供了很多静态方法,可以构造上述两个实现类的实例。
Set<SizeEnum> enumSet0 = EnumSet.allOf(SizeEnum.class);
System.out.print("EnumSet.allOf: ");
System.out.println(enumSet0);
System.out.print("EnumSet.noneOf: ");
Set<SizeEnum> enumSet1 = EnumSet.noneOf(SizeEnum.class);
System.out.println(enumSet1);
System.out.print("add item LARGE MEDIUM EXTRA_LARGE: ");
enumSet1.add(SizeEnum.LARGE);
enumSet1.add(SizeEnum.MEDIUM);
enumSet1.add(SizeEnum.EXTRA_LARGE);
System.out.println(enumSet1);
System.out.print("EnumSet.of LARGE SMALL: ");
Set<SizeEnum> enumSet2 = EnumSet.of(SizeEnum.LARGE, SizeEnum.SMALL);
System.out.println(enumSet2);
运行结果如下:
EnumSet.allOf: [SMALL, MEDIUM, LARGE, EXTRA_LARGE]
EnumSet.noneOf: []
add item LARGE MEDIUM EXTRA_LARGE: [MEDIUM, LARGE, EXTRA_LARGE]
EnumSet.of LARGE SMALL: [SMALL, LARGE]
可以发现的是,EnumSet中提供了一些静态方法,构造EnumSet实例,至于具体方法,下面讲解。还有就是,EnumSet也可以保证元素之间按照枚举类中枚举值的定义有序。下面通过一个例子,看一下EnumSet的具体应用:
//库存详情类
@Getter
@Setter
@AllArgsConstructor
public class StockInfo {
//库存商品id
private Long productId;
//库存商品id对应的尺码
private Set<SizeEnum> stockSizes;
}
List<StockInfo> stockInfoList = Lists.newArrayList();
stockInfoList.add(new StockInfo(1L, EnumSet.of(SizeEnum.SMALL, SizeEnum.MEDIUM, SizeEnum.EXTRA_LARGE)));
stockInfoList.add(new StockInfo(2L, EnumSet.of(SizeEnum.SMALL, SizeEnum.MEDIUM, SizeEnum.EXTRA_LARGE)));
stockInfoList.add(new StockInfo(3L, EnumSet.of(SizeEnum.SMALL, SizeEnum.EXTRA_LARGE)));
stockInfoList.add(new StockInfo(4L, EnumSet.of(SizeEnum.SMALL, SizeEnum.MEDIUM)));
System.out.print("这些型号的商品有库存: ");
Set<SizeEnum> allSizeEnum0 = EnumSet.noneOf(SizeEnum.class);
stockInfoList.forEach(ele -> {
allSizeEnum0.addAll(ele.getStockSizes());
});
System.out.println(allSizeEnum0);
System.out.print("这些型号的商品没有库存: ");
Set<SizeEnum> allSizeEnum1 = EnumSet.allOf(SizeEnum.class);
stockInfoList.forEach(ele -> {
allSizeEnum1.removeAll(ele.getStockSizes());
});
System.out.println(allSizeEnum1);
System.out.print("这些型号所有的商品都有库存: ");
Set<SizeEnum> allSizeEnum2 = EnumSet.allOf(SizeEnum.class);
stockInfoList.forEach(ele -> {
allSizeEnum2.retainAll(ele.getStockSizes());
});
System.out.println(allSizeEnum2);
System.out.print("这些型号至少有三种商品有库存: ");
Map<SizeEnum, Integer> sizeCountMap = Maps.newEnumMap(SizeEnum.class);
stockInfoList.forEach(ele -> {
ele.getStockSizes().forEach(size -> {
sizeCountMap.compute(size, (k, v) -> Objects.isNull(v) ? 1 : ++v);
});
});
Map<SizeEnum, Integer> finalSizeMap = sizeCountMap.entrySet().stream().filter(ele -> ele.getValue() >= 3)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
System.out.println(finalSizeMap);
运行结果:
这些型号的商品有库存: [SMALL, MEDIUM, EXTRA_LARGE]
这些型号的商品没有库存: [LARGE]
这些型号所有的商品都有库存: [SMALL]
这些型号至少有三种商品有库存: {MEDIUM=3, SMALL=4, EXTRA_LA