Как вернуть false, если коллекция java содержит два одинаковых элемента - PullRequest
0 голосов
/ 11 июня 2019

У меня есть Collection<Event>. Event выглядит примерно так

public class Event {

   private Integer id;
   private LocalDateTime localDateTime;

   // getters, setters omitted

}

Каждый Event в этом Collection должен иметь уникальные id и localDateTime. Как я могу сделать эту проверку с помощью потокового API и вернуть true, если условие выполнено?

Ответы [ 4 ]

1 голос
/ 11 июня 2019

Это класс Event, который вам понадобится;

class Event {

    private Integer id;

    private LocalDateTime localDateTime;

    public Integer getId() {
        return id;
    }

    public LocalDateTime getLocalDateTime() {
        return localDateTime;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public void setLocalDateTime(LocalDateTime localDateTime) {
        this.localDateTime = localDateTime;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Event event = (Event) o;
        return id.equals(event.id) &&
                localDateTime.equals(event.localDateTime);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, localDateTime);
    }

    public static boolean hasDuplicates(List<Event> events) {
        /*
            return events
            .stream()
            .noneMatch(e -> events
                    .stream()
                    .filter(ev -> ev.equals(e)).count() > 1);
         */
         return events.stream()
             .distinct()
             .count() != events.size(); // Kudos to @Holger for this approach.
    }
}

Этот hasDuplicates является функцией static, поэтому он не окажет никакого влияния на создание вашего объекта.Вы можете использовать его как служебный метод для проверки дубликатов.Вам понадобится только одна строка проверки.

0 голосов
/ 11 июня 2019

Прежде всего, переопределите метод equals() и hashcode() и напишите его так:

@Override
public boolean equals(Object o){
if (o instanceof Event){
    Event e = (Event) o;
    return e.id.equals(this.id) && e.localDateTime.equals(this.localDateTime);
}
else return false;
}

@Override
public int hashCode(){
return Objects.hash(id,localDateTime); //this is the default implementation, up to you to implement it in a better way
}

Затем вы можете использовать поток, подобный этому, чтобы проверить, есть ли дубликаты:

public boolean checkAllUnique(Collection<Event> col){
    return col.stream().allMatch(new HashSet<>()::add);
}
0 голосов
/ 11 июня 2019

Вы можете использовать два HashSet в качестве резервных коллекций для хранения уникальных элементов и перебора списка событий как:

public boolean duplicateExists(List<Event> eventList) {
    Set<Integer> ids = new HashSet<>();
    Set<LocalDateTime> localDateTimes = new HashSet<>();
    return eventList.stream()
            .anyMatch(event -> !ids.add(event.getId()) ||
                    !localDateTimes.add(event.getLocalDateTime()));
}
0 голосов
/ 11 июня 2019
 import java.util.concurrent.atomic.AtomicInteger;
    public class Event {

       private static final AtomicInteger idGenerator = new AtomicInteger(1000);
       private Integer id;
       private LocalDateTime localDateTime;

       public Event(){
          id = idGenerator.getAndIncrement();
       }
       // getters, setters omitted
}

Проверка кода

public class Test {
    public static void main(String[] args) {
        for(int i = 0; i < 10; ++ i){
            System.out.println(new Event().getId());
        }
    }
}

Вывод

1000 1001 1002 1003 1004 1005 1006 1007 1008 1009
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...