Повторяющиеся значения в коллекции Set? - PullRequest
9 голосов
/ 21 января 2010

Можно ли разрешить повторяющиеся значения в коллекции Set?

Есть ли способ сделать элементы уникальными и иметь несколько их копий? Существуют ли какие-либо функции для коллекции Set для дублирования значений в ней?

Ответы [ 13 ]

26 голосов
/ 21 января 2010

Когда-либо рассматривалось использование java.util.List вместо?

В противном случае я бы порекомендовал Multiset из Google Guava (преемник Google Collections , который изначально рекомендован этим ответом.).

12 голосов
/ 21 января 2010

Само определение набора запрещает дубликаты. Я думаю, что, возможно, вы захотите использовать другую структуру данных, например, List , которая разрешит дублирование.

Есть ли способ сделать элементы уникальными и иметь несколько их копий?

Если по какой-то причине вам действительно нужно do хранить дубликаты в наборе, вам нужно либо обернуть их в какой-либо объект-держатель, либо переопределить equals () и hashCode () объекты вашей модели, чтобы они не оценивались как эквивалентные (и даже , что завершится ошибкой, если вы пытаетесь хранить ссылки на один и тот же физический объект несколько раз).

Я думаю, вам нужно переоценить то, что вы пытаетесь достичь здесь, или, по крайней мере, объяснить это нам более четко.

2 голосов
/ 22 января 2010

Взгляд Солнца на "сумки" (мультисеты АКА):

Мы чрезвычайно сочувственно относимся к стремлению к коллекциям с сохранением типов. Вместо того, чтобы добавлять «бинты» в структуру, которая обеспечивает безопасность типов специальным образом, структура была разработана для объединения со всеми предложениями параметризованных типов, которые в настоящее время обсуждаются. В случае, если параметризованные типы добавляются в язык, вся структура коллекций будет поддерживать безопасное использование типов во время компиляции, без необходимости явного приведения. К сожалению, этого не произойдет в версии 1.2. В то же время люди, которым нужна безопасность типов во время выполнения, могут реализовывать свои собственные функции стробирования в коллекциях «оболочек», окружающих коллекции JDK.

( источник ; обратите внимание, что он старый и, возможно, устарел.)

Помимо API коллекций Google вы можете использовать Apache Commons Collections.

Коллекции Apache Commons:

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

Javadoc для Bag

2 голосов
/ 21 января 2010

Из документов:

"наборы не содержат пары элементов e1 и е2 такие, что е1.equals (е2), и при самый один null элемент "

Так что, если ваши объекты должны были переопределить .equals (), чтобы он возвращал разные значения для любых объектов, которые вы намереваетесь хранить, вы можете хранить их отдельно в Set (вы также должны переопределить hashcode () ).

Однако само определение Set в Java:

"Коллекция, которая не содержит дубликаты элементов. «

Так что вам действительно лучше использовать List или что-то еще здесь. Возможно Map, если вы хотите хранить повторяющиеся значения на основе разных ключей.

1 голос
/ 09 августа 2014

Это звучит как вопросы для интервью, поэтому я отвечу на них как вопросы для интервью ...

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

Да, но для этого необходимо, чтобы лицо, реализующее Set, нарушило проектный контракт , на котором строится Set. По сути, я мог бы написать класс, который расширяет Set и не выполняет обещания Set.

Кроме того, возможны другие нарушения. Я мог бы использовать Set реализацию, которая опирается на Java hashCode() контракт. Тогда, если я предоставлю Object, который нарушает контракт хеш-кода Java, я мог бы поместить два набора в набор, которые равны, но дают разные хеш-коды (потому что они могут не проверяться на равенство друг с другом из-за того, что находятся в разных хэш-ведро цепи.

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 не имеет никаких функций для обнаружения / сообщения о дубликатах; однако, он основан на интерфейсе Коллекции, который должен поддерживать интерфейс Списка, таким образом, можно передавать дубликаты в Набор; однако, правильно реализованный Set будет просто игнорировать дубликаты и предоставит одну копию каждого элемента, определенного как уникальный.

1 голос
/ 21 января 2010

Я не верю, что вы можете иметь повторяющиеся значения в наборе. Набор определяется как набор уникальных значений. Возможно, вам лучше использовать ArrayList.

0 голосов
/ 01 мая 2019

Ну, в этом случае мы пытаемся сломать цель конкретной коллекции. Если мы хотим разрешить дублирование записей, просто используйте список или мультикарту.

0 голосов
/ 29 ноября 2012
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;}
    }
}
0 голосов
/ 24 октября 2012

Вы можете сделать это, переопределив хеш-код, как указано ниже:

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--");
    }
}
0 голосов
/ 22 июля 2010

Этот вопрос был задан мне также в интервью. Я думаю, что ответ, конечно, Set не допустит дублирования элементов, и вместо этого ArrayList или другие коллекции должны использоваться для того же самого, однако переопределение equals () для типа объекта, хранящегося в наборе, позволит вам манипулировать сравнением логика. И, следовательно, вы можете хранить дубликаты элементов в наборе. Это скорее хак, который позволил бы использовать неуникальные элементы в наборе и конечно, не рекомендуется в коде производственного уровня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...