Java编程拾遗『EnumSet』

上篇文章讲了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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值