Set集合中的重复值?

是否可以在Set集合中允许重复值?

有没有办法让元素独一无二并有一些副本? Set集合中是否有任何具有重复值的函数?

曾经考虑使用java.util.List吗?

否则,我会推荐Google Guava的Multiset ( Google Collections的inheritance者,这个答案最初建议使用)。

Set的定义不允许重复。 我想也许你想使用另一种数据结构,比如List ,这将允许重复。

有没有办法让元素独一无二并有一些副本?

如果由于某种原因你真的需要在一个集合中存储重复项,你需要将它们包装在某种holder对象中,或者覆盖模型对象的equals()和hashCode(),这样它们就不会评估等价(如果你试图多次存储对同一物理对象的引用,那么即使这样也会失败)。

我认为你需要重新评估你在这里想要完成的事情,或者至少向我们解释清楚。

来自javadocs:

“集合不包含元素对e1和e2,使得e1.equals(e2),并且最多只有一个null元素”

因此,如果您的对象重写.equals()以便它为您要存储的任何对象返回不同的值,那么您可以将它们分别存储在Set (您还应该重写hashcode())。

但是,Java中Set定义是,

“一个不包含重复元素的集合。”

所以你最好在这里使用List或其他东西。 如果您想根据不同的密钥存储重复值,也许是Map

Sun对“包包”的看法(AKA multisets):

我们非常同情对类型安全的collections品的渴望。 该框架不是为以临时方式强制实施类型安全的框架添加“创可贴”,而是设计为与当前正在讨论的所有参数化类型提案相互作用。 如果将参数化类型添加到语言中,则整个集合框架将支持编译时类型安全使用,而无需显式强制转换。 不幸的是,这不会发生在1.2版本中。 与此同时,希望运行时类型安全的人可以在围绕JDK集合的“包装器”集合中实现自己的选通function。

( 来源 ;注意它很旧,可能已经过时了。)

除了Google的集合API,您还可以使用Apache Commons Collections。

Apache Commons集合:

http://commons.apache.org/collections/

Javadoc for Bag

我不相信你可以在一个集合中有重复的值。 集合被定义为唯一值的集合。 你可能最好使用ArrayList。

这听起来像面试问题,所以我会像面试问题一样回答……

 Is it possible to allow duplicate values in the Set collection? 

是的,但它要求实施Set的人违反了建立Set设计合同 。 基本上,我可以编写一个扩展Set的类,并且不会强制执行Set的承诺。

此外,还可能发生其他违规行为。 我可以使用依赖于Java的hashCode()契约的Set实现。 然后,如果我提供了一个违反Java的哈希码契约的Object ,我可能会将两个对象放入相同的集合中,但是可能会有不同的哈希码(因为它们可能不会因为处于不同的哈希桶中而彼此相等地进行检查链。

 Is there any way to make the elements unique and have some copies of them? 

它主要取决于你如何定义唯一性。 如果对象的唯一性由其值确定,则可以具有相同唯一对象的多个副本; 但是,如果对象的唯一性由其实例确定,那么根据定义,不可能拥有同一对象的多个副本。 但是,您可以对它们进行多次引用。

 Is there any functions for Set collection for having duplicate values in it? 

Set接口没有任何检测/报告重复项的function; 但是,它基于Collections接口,它必须支持List接口,因此可以将重复项传递给Set; 但是,正确实现的Set将忽略重复项,并呈现确定为唯一的每个元素的一个副本。

我不这么认为。 唯一的方法是使用List。 你也可以使用函数equals(),hashcode()或compareTo()进行欺骗,但它会变得很笨拙。

没有机会….你不能在SET界面中有重复的值…如果你想要重复,那么你可以尝试Array-List

如上所述,为任务选择正确的集合,并且List可能就是您所需要的。 使用equals(),hashcode()或compareTo()来破坏身份通常只是简单地将实例楔入错误的集合开始。 更糟糕的是它可能会破坏应用程序的其他区域中的代码,这些代码依赖于这些方法产生有效的比较结果,并且很难调试或追踪这些错误。

我也在接受采访时问过这个问题。 我认为答案是,当然Set不允许重复元素,而ArrayList或其他集合应该用于相同的,但是对于存储在集合中的对象类型的重写equals()将允许您操作比较逻辑。 因此,您可以在集合中存储重复的元素。 它更像是一个hack,它允许在生产级代码中使用Set和ofcourse中的非唯一元素。

您可以通过覆盖哈希码来实现,如下所示:

 public class Test { static int a=0; @Override public int hashCode() { a++; return a; } public static void main(String[] args) { Set s=new HashSet(); Test t1=new Test(); Test t2=t1; s.add(t1); s.add(t2); System.out.println(s); System.out.println("--Done--"); } } 
 public class SET { public static void main(String[] args) { Set set=new HashSet(); set.add(new AB(10, "pawan@email")); set.add(new AB(10, "pawan@email")); set.add(new AB(10, "pawan@email")); Iterator it=set.iterator(); while(it.hasNext()){ Object o=it.next(); System.out.println(o); } } } public class AB{ int id; String email; public AB() { System.out.println("DC"); } AB(int id,String email){ this.id=id; this.email=email; } @Override public String toString() { // TODO Auto-generated method stub return ""+id+"\t"+email;} } }