Java如何重写TreeSet的add方法使其最多仅添加4个元素
方案1:自定义限长TreeSet子类(适配现有代码的最小改动方案)
你只需要继承TreeSet重写add方法,在元素数量达到阈值后直接拒绝添加新元素即可,实现代码如下:
import java.util.TreeSet; public class LimitedTreeSet<E> extends TreeSet<E> { // 最多允许存储的元素个数 private static final int MAX_SIZE = 4; @Override public boolean add(E e) { // 已有元素达到上限直接返回添加失败 if (size() >= MAX_SIZE) { return false; } return super.add(e); } @Override public boolean addAll(java.util.Collection<? extends E> c) { boolean modified = false; for (E e : c) { if (add(e)) { modified = true; } // 达到上限就停止遍历添加 if (size() >= MAX_SIZE) { break; } } return modified; } }
之后你原来的分组代码只需要修改下游收集器的构造引用即可:
Map<Integer, Set<Person>> stream_exo = ListOfPerson.stream() .collect( Collectors.groupingBy( p -> p.getYear(), TreeMap::new, Collectors.toCollection(LimitedTreeSet::new) ) );
注意事项
- 该实现严格按照你给出的原生
TreeSet逻辑扩展,没有破坏原有排序、去重的特性,只有在元素数量超过4的时候才会拦截添加操作 - 重写
addAll是为了避免批量添加操作绕过单元素添加的数量校验,如果你的场景不会用到批量添加可以省略该方法
方案2:无需自定义类的Stream实现(可选)
如果你不想额外定义类,也可以通过Collectors.collectingAndThen实现同样效果,代码如下:
Map<Integer, Set<Person>> stream_exo = ListOfPerson.stream() .collect(Collectors.groupingBy( Person::getYear, TreeMap::new, Collectors.collectingAndThen( Collectors.toCollection(TreeSet::new), set -> set.stream().limit(4).collect(Collectors.toCollection(TreeSet::new)) ) ));
这种方案是先把同分组的所有元素收集为TreeSet,再截取前4个元素生成新的TreeSet,适合数据量不大的场景。
内容的提问来源于stack exchange,提问作者jaki hart
相关产品推荐
相关产品推荐

