Set集合中的重复值?

时间:2010-01-21 20:17:31

标签: java collections

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

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

13 个答案:

答案 0 :(得分:26)

有没有考虑使用java.util.List代替?

否则我会建议Multiset Google GuavaGoogle Collections的后继者{{3}},这个答案最初建议使用。)。

答案 1 :(得分:12)

Set的definition非禁止重复。我想也许您想要使用另一种数据结构,例如List,这将允许重复。

  

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

如果由于某种原因你真的需要在一个集合中存储重复项,你需要将它们包装在某种holder对象中,否则重写equals()和hashCode()您的模型对象,以便它们不评估为等效(如果您试图多次存储对同一物理对象的引用,甚至 将失败)。

我认为您需要重新评估您要在此处完成的工作,或至少向我们解释清楚。

答案 2 :(得分:2)

来自javadocs:

  

“集合不包含元素对e1   和e2使得e1.equals(e2)和at   大多数null元素“

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

但是,Java中Set的定义是,

  

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

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

答案 3 :(得分:2)

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

  

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

source;注意它已经过时了,可能已经过时了。)

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

Apache Commons Collections:

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

Javadoc for Bag

答案 4 :(得分:1)

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

答案 5 :(得分:1)

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

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

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

此外,还可能发生其他违规行为。我可以使用依赖于Java Set合同的hashCode()实现。然后,如果我提供了违反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接口没有任何检测/报告重复项的功能;但是,它基于Collections接口,它必须支持List接口,因此可以将重复项传递给Set;但是,正确实现的Set将忽略重复项,并提供确定为唯一的每个元素的一个副本。

答案 6 :(得分:0)

我不这么认为。唯一的方法是使用List。您还可以使用函数equals(),hashcode()或compareTo()进行欺骗,但这样做会很麻烦。

答案 7 :(得分:0)

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

答案 8 :(得分:0)

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

答案 9 :(得分:0)

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

答案 10 :(得分:0)

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

public class Test  
{  
    static int a=0;  

    @Override  
    public int hashCode()  
    {  
        a++;  
        return a;  
    }

    public static void main(String[] args)
    {
        Set<Test> s=new HashSet<Test>();
        Test t1=new Test();
        Test t2=t1;
        s.add(t1);
        s.add(t2);
        System.out.println(s);
        System.out.println("--Done--");
    }
}

答案 11 :(得分:0)

好吧,在这种情况下,我们试图破坏特定集合的目的。如果我们要允许重复记录,只需使用列表或多图。

答案 12 :(得分:-1)

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;}
    }
}