2017-02-12 12 views
1

У меня есть 2 набора хэшей, содержащих x количество «Имена» (Объект). Что я хотел бы сделать, это выяснить, если мои «Имена» в Names1 или в Names2?Сравнение двух наборов Java

public static void main (String[] args) { 

Set<Name> Names1 = new HashSet<Name>(); 
    Names1.add(new Name("Jon")); 
    Names1.add(new Name("Mark")); 
    Names1.add(new Name("Mike")); 
    Names1.add(new Name("Helen")); 
    Set<Name> Names2 = new HashSet<Name>(); 
    Names2.add(new Name("Mark")); 
    Names2.add(new Name("Mike")); 
    Names2.add(new Name("Sally")); 



    Set<Name> listCommon = new HashSet<Name>(); 

    for (Name element : Names1) { 
     if (!Names2.contains(element)) { 
      listCommon.add(element); 
     } 
    } 

    for (Name element : listCommon) { 
     System.out.println(element.getNameString()); 
    } 

} 
public class Name { 
String ord; 

Name(String ord1){ 
    ord = ord1; 
} 

public String getNameString(){ 
    return ord; 
} 
} 

Так что, когда я запустил этот код, я не получил никакого вывода вообще, вызывают

'if (!Names2.contains(element)) {' 

никогда не произошло. Но то, что я хотел бы получить в качестве вывода, будет Jon и Helen. Поскольку они не находятся в Names2.

+0

удалить ваш! оператора для вычисления общих имен. – algojava

+3

Являются ли методы 'equals' и' hashCode' в вашем классе 'Name' удалены для краткости или действительно отсутствуют? –

+2

Вам нужно переопределить метод 'equals' и' hashCode' из суперкласса, который будет классом 'Object' –

ответ

0

Если у вас есть equals и hashCode методы переопределены в Name классе, вы можете использовать retainAll метод Set (Javadoc here), чтобы выяснить общие элементы. Например.

public static void main(String[] args) throws IOException { 
    Set<Name> Names1 = new HashSet<Name>(); 
    Names1.add(new Name("Jon")); 
    Names1.add(new Name("Mark")); 
    Names1.add(new Name("Mike")); 
    Names1.add(new Name("Helen")); 
    Set<Name> Names2 = new HashSet<Name>(); 
    Names2.add(new Name("Mark")); 
    Names2.add(new Name("Mike")); 
    Names2.add(new Name("Sally")); 

    Names1.retainAll(Names2); 

    for(Name name : Names1){ 
     System.out.println(name.getName()); 
    } 
} 

Вот пример класса Name с equals и hashCode методами:

class Name{ 
    private String name; 

    public Name(String name){ 
     this.name = name; 
    } 

    @Override 
    public int hashCode(){ 
     return null != name ? name.hashCode() : 0; 
    } 

    @Override 
    public boolean equals(Object o){ 
     return o instanceof Name 
       && ((Name)o).name != null 
       && this.name != null 
       && ((Name)o).name.equals(this.name); 
    } 

    public String getName() { 
     return name; 
    } 
} 

Пожалуйста, обратите внимание, что retainAll метод изменяет set его называют на (Names1 в нашем случае). Если вы хотите сохранить исходный набор, вы можете скопировать элементы в другой набор и вызвать retainAll на этом экземпляре.

0

Ваш Set::contains чек не будет работать, потому что вы не смогли переопределить Object::equals. Реализация по умолчанию Object::equals проверяет ссылочное равенство (==), то есть имя должно быть тем же самым экземпляром, который считается равным.

Как уже было сказано, правильная вещь для вас - это реализовать hashCode и равно в вашем классе Name.

Несоблюдение этого требования потребовало бы проведения итерации по набору и испытаниям , чтобы сделать свою собственную ручную и неэффективную версию теста Set::contains.