Создать карту, удалив дубликаты из списка в зависимости от условий - PullRequest
4 голосов
/ 20 февраля 2020

Я хочу получить список без дублирования на основе условия, используя java 8, лямбда-выражения. Допустим, у меня есть следующий код:

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

public class Main {

    class Person {
        private String name;
        private int age;

        public Person(String name, int age) {
           this.name = name;
           this.age = age;
        }

        public String getName() {
            return this.name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return this.age;
        }

        public void setName(int age) {
            this.age = age;
        }
    }

    public static void main(String[] args) {

        Main main = new Main();
        main.createList();
    }

    public void createList() {

        List<Person> p = new ArrayList<Person>();
        p.add(new Person("william", 34));
        p.add(new Person("billie", 62));
        p.add(new Person("Loise", 37));
        p.add(new Person("Margot", 12));
        p.add(new Person("billie", 63));
        p.add(new Person("billie", 61));

        System.out.println("show People initially");
        show(p);

        // It's going to be duplicated when it has the same name
        // It'll keep the older person. For example, for billie it should keep billie -> 63

        p = removeDuplicate(p, person -> buildPersonKey(person));

        System.out.println("show People After");
        show(p);

    }

    public void show(List<Person> pList) {
        for (Person p: pList) {
            System.out.println(p.getName() + "-Age: " + p.getAge());
        }
    }



    public <T> List<T> removeDuplicate(List<T> dataList, Function<? super T, ?> keyFunction) {
        return
                new ArrayList<>(dataList.stream()
                        .collect(Collectors.toMap(
                                p -> (keyFunction.apply(p)),
                                p -> p,
                                (oldValue, newValue) -> newValue))  
                        .values());
    }

    public String buildPersonKey(Person p) {
        return p.getName();
    }
}

Это мой текущий вывод:

show People initially
william-Age: 34
billie-Age: 62
Loise-Age: 37
Margot-Age: 12
billie-Age: 63
billie-Age: 61
show People After
william-Age: 34
billie-Age: 61 // Here I want "billie-Age: 63"
Loise-Age: 37
Margot-Age: 12

Эта строка (oldValue, newValue) -> newValue)) является ключом, но вот что мне нужно, это Если выражение, что-то вроде mapValueOld.getAge ()> mapValueNew.getAge ()? mapValueOld.getAge (): mapValueNew.getAge ()

Есть идеи, как мне это получить? Спасибо

1 Ответ

3 голосов
/ 20 февраля 2020

Поскольку ваш метод removeDuplicate является родовым c, вам нужно передать ему функцию, которая выбирает между двумя элементами, имеющими одинаковый ключ:

public <T> List<T> removeDuplicate(List<T> dataList, Function<? super T, ?> keyFunction, BinaryOperator<T> chooser) {
    return
            new ArrayList<>(dataList.stream()
                    .collect(Collectors.toMap(keyFunction,
                                              Function.identity(),
                                              chooser))
                    .values());
}

и вызвать метод с помощью:

p = removeDuplicate(p,
                    person -> buildPersonKey(person),
                    (p1,p2) -> p1.getAge() >= p2.getAge() ? p1 : p2);
...