Метод Different () не возвращает отдельные элементы для потока элементов HashSet - PullRequest
2 голосов
/ 16 марта 2019

Допустим, у меня есть класс Employee с правильно переопределенными равными и методом хэш-кода.

public class Employee {

private int eno;
private String firstName;
private String lastName;

@Override
public int hashCode() {
    System.out.println("hashcode called");
    final int prime = 31;
    int result = 1;
    result = prime * result + eno;
    result = prime * result + ((firstName == null) ? 0 : firstName.hashCode());
    result = prime * result + ((lastName == null) ? 0 : lastName.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    System.out.println("equals called");
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Employee other = (Employee) obj;
    if (eno != other.eno)
        return false;
    if (firstName == null) {
        if (other.firstName != null)
            return false;
    } else if (!firstName.equals(other.firstName))
        return false;
    if (lastName == null) {
        if (other.lastName != null)
            return false;
    } else if (!lastName.equals(other.lastName))
        return false;
    return true;
}
}

Класс тестирования, как показано ниже

class Test {

    public static void main(String[] args) {

        Employee e1 = new Employee(1, "Karan", "Mehara");
        Employee e2 = new Employee(2, "Rajesh", "Shukla");

        Set<Employee> emps= new HashSet<>();
        emps.add(e1);
        emps.add(e2);
        System.out.println(emps);

        // No such requirement just for testing purpose modifying 
        e2.setEno(1);
        e2.setFirstName("Karan");
        e2.setLastName("Mehara");

        System.out.println(emps);

        emps.stream().distinct().forEach(System.out::println);
    }

}

Вывод вышеуказанной программы:

[Сотрудник [eno = 1, firstName = Karan, lastName = Mehara], Сотрудник [eno = 2, firstName = Rajesh, lastName = Shukla]]

[Сотрудник [eno = 1, firstName = Karan, lastName = Mehara], сотрудник [eno = 1, firstName = Karan, lastName = Mehara]]

сотрудник [eno = 1, firstName = Karan, lastName = Mehara]

Сотрудник [eno = 1, firstName = Karan, lastName = Mehara]

Почему метод Different () возвращает повторяющиеся элементы ??

Согласно методам equals () и hashcode () класса сотрудников оба объекта одинаковы.

Я заметил, что при вызове метода Different () equals () и метода hashcode () не получит вызов для потока Установите реализацию , но он получит вызов для потока Список реализации .

В соответствии с JavaDoc говорит отдельный () Возвращает поток, состоящий из отдельных элементов (в соответствии с Object.equals (Object)) этого потока.

/**
     * Returns a stream consisting of the distinct elements (according to
     * {@link Object#equals(Object)}) of this stream.
     *
     * <p>For ordered streams, the selection of distinct elements is stable
     * (for duplicated elements, the element appearing first in the encounter
     * order is preserved.)  For unordered streams, no stability guarantees
     * are made.
     *
     * <p>This is a <a href="package-summary.html#StreamOps">stateful
     * intermediate operation</a>.
     *
     * @apiNote
     * Preserving stability for {@code distinct()} in parallel pipelines is
     * relatively expensive (requires that the operation act as a full barrier,
     * with substantial buffering overhead), and stability is often not needed.
     * Using an unordered stream source (such as {@link #generate(Supplier)})
     * or removing the ordering constraint with {@link #unordered()} may result
     * in significantly more efficient execution for {@code distinct()} in parallel
     * pipelines, if the semantics of your situation permit.  If consistency
     * with encounter order is required, and you are experiencing poor performance
     * or memory utilization with {@code distinct()} in parallel pipelines,
     * switching to sequential execution with {@link #sequential()} may improve
     * performance.
     *
     * @return the new stream
     */
    Stream<T> distinct();

1 Ответ

6 голосов
/ 16 марта 2019

A Set определено как «Коллекция, не содержащая повторяющихся элементов». Поэтому метод Stream distinct для Set, скорее всего, будет реализован так, чтобы вообще ничего не делать, поскольку уже гарантировано, что значения уникальны.

То, что вы сделали, явно упоминается в Javadoc:

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

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