Как сгруппировать по нескольким параметрам объекта списка в Java 8 и удалить дубликаты строк? - PullRequest
1 голос
/ 09 апреля 2019

Это мой код:

public class User{
        private String id;
        private String userName;
        private Long birthDate;
        private String address;
        private boolean enabled;
        //Constructors
        // Getters && Setters
        ...
}

public class ServiceUser{
    List<User> users=new ArrayList<>();

    public ServiceUser(){
        users.add(new User("OPS","MESSI",15454222454L,"ADRESSE 1",true))
        users.add(new User("TA1","RICHARD",1245485456787L,"ADRESSE 1",true));
        users.add(new User("XA5","LANG",659854575424L,"ADRESSE 2",true));
        users.add(new User("DS7","RICHARD",1245485456787L,"ADRESSE 1",false));
        users.add(new User("OPD6","LONG",659854575424L,"ADRESSE 2",false));
        ...
    }

    protected List<User> getFiltredUsers(){
        // TODO here
    }
}

Я хотел бы получить список пользователей, таких как:

User("OPS","MESSI",15454222454L,"ADRESSE 1",true)

Как удалить все дублирующиеся строки, которые имеют одинаковые userName, birthDate, address?

Примечание: список пользователей возвращается базой данных, и только для Пример, который я выразил так.

Ответы [ 2 ]

2 голосов
/ 09 апреля 2019

Следующий код удаляет дубликаты и возвращает только отдельные элементы из вашего списка пользователей:

//used for grouping them by name, birthday and address
static Function<User, List<Object>> groupingComponent = user ->
Arrays.<Object>asList(user.getName(), user.getBirthday(),user.getAddress());
//grouping method used for grouping them by groupingComponent and frequency of it
private static Map<Object, Long> grouping(final List<User> users) {
    return users.stream()
            .collect(Collectors.groupingBy(groupingComponent, Collectors.counting()));
}
//filtering method used for filtering lists if element is contained more than 1 within a list
private static List<Object> filtering(final Map<Object, Long> map) {
    return map.keySet()
            .stream()
            .filter(key -> map.get(key) < 2)
            .collect(Collectors.toList());
}

Простое использование будет: filtering(grouping(users));

System.out.println(filtering(grouping(users)));

ОБНОВЛЕНИЕ 3: Честно говоря, это немного сложно из-за этих трех параметров (день рождения, имя и адрес).Самый простой способ, о котором я мог бы подумать сейчас, - это реализовать методы hashCode и equals в вашем классе User (например, чтобы пометить пользователей одинаковыми, если у них три одинаковых значения):

@Override
public int hashCode() {
    return (43 + 777);
}
@Override
public boolean equals(Object obj) {
    // checks to see whether the passed object is null, or if it’s typed as a 
    // different class. If it’s a different class then the objects are not equal.
    if (obj == null || getClass() != obj.getClass()) {
        return false;
    }
    // compares the objects’ fields.
    User user = (User) obj;
    return getName().contains(user.getName())
            && getBirthday() == user.getBirthday()
            && getAddress()== user.getAddress();
}

и следующий метод для удалениявсе дубликаты

   public static List<User> filter(List<User> users) {
        Set<User> set = new HashSet<>();
        List<User> uniqueUsers = new ArrayList<>();
        List<User> doubleUsers = new ArrayList<>();
        Map<Boolean, List<User>> partitions = users.stream().collect(Collectors.partitioningBy(user -> set.add(user) == true));
        uniqueUsers.addAll(partitions.get(true));
        doubleUsers.addAll(partitions.get(false));
        uniqueUsers.removeAll(doubleUsers);
        return uniqueUsers;
    }
0 голосов
/ 09 апреля 2019

Вместо List:

List<User> users=new ArrayList<>();

Вы можете использовать Set (в этом примере я использовал HashSet):

Set<User> users=new HashSet<>();

Sets не разрешать дубликаты, поэтому вам даже не нужно фильтровать.

Смотри также: https://docs.oracle.com/javase/7/docs/api/java/util/Set.html

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