在自定义集中添加重复项

时间:2017-04-07 18:26:01

标签: java collections

调整API领先一步。

基本上,Set不允许重复输入。

但是当我写一个自定义的Set时,如何才能实现允许添加重复项?

4 个答案:

答案 0 :(得分:3)

由数学definition组成的集合是:

  

明确定义的不同对象集合

Java definition

也重申了这一点
  

不包含重复元素的集合。更正式地说,集合不包含元素对e1和e2,使得e1.equals(e2)和至多一个null元素。正如其名称所暗示的,该界面对数学集抽象进行建模。

因此,在您的情况下,您需要使用List才能拥有重复项。

答案 1 :(得分:2)

在Java中,

Set根据定义是一个不能重复的数据结构。因此,如果您想要一个允许重复的数据结构,您可能希望改为使用java.util.List

答案 2 :(得分:2)

简单而严肃的回答:这样做。

你基本上是在问:我应该如何绘制一个有四个角的三角形?或者我如何用鸡翅准备素食餐??

Java Set界面意味着不允许重复。这是该概念的基本基石之一。并且没有"但是"。

您建议违反 Set给出的合同。

换句话说:继承和多态不仅仅是写下A extends B。在创建子类时,必须要了解规则;或接口的新实现。例如Liskov Substitution principle

假设你得到了:

Set<Integer> someSet = new HashSet<Integer>;
someSet.add(1); someSet.add(1);
System.out.println(someSet);

之后应该在集合中显示一个条目。如果你现在去

Set<Integer> someSet = new YourSpecialDuplicatesAllowingSet<Integer>;
someSet.add(1); someSet.add(1);

突然...... someSet可能包含两个条目。

长话短说:你的想法只能实现两件事:困惑别人;从而为丑陋的bug创造了很多潜力。 错误;因为那些事情是&#34;合同&#34;以这种方式违反通常很难找到和调试!

鉴于你的评论:这样做很容易:

public class FakedSet<T> implements Set<T> {
  private final List<T> elements = new ArrayList<>();
  @Override
  public void add(T elem) { elements.add(T); }

等等;你会@Override Set接口有的所有方法;并尝试以某种方式实现它们。不要以合理的方式询问如何做到这一点;因为好;这是不可能的!

答案 3 :(得分:0)

正如其他人已经正确陈述的那样,不存在包含重复的集合,既不是Java也不是数学。

但是你可能想要一张可以计算你有多少重复项的地图:

Map<Whatever, Long> multiset = new HashMap<>();

要添加元素,请使用merge方法:

multiset.merge(someElement, 1, (oldValue, value) -> oldValue + 1);

要删除元素,您可能需要使用computeIfPresent方法:

multiset.computeIfPresent(someElement, (key, value) -> (value == 1 ? null : value - 1));