筛选由属性区分并按日期排序的列表的好方法

Sup*_*shi 7 java arrays java-8 java-stream

我有很简单的事情要做,我有这样的人员名单:

[{
    name: John,
    date: 01-01-2018,
    attend: true
},
{
    name: Adam,
    date: 01-01-2018,
    attend: false
},
{
    name: Adam,
    date: 01-02-2018,
    attend: true
},
{
    name: JOHN,
    date: 01-02-2018,
    attend: false
}]
Run Code Online (Sandbox Code Playgroud)

这个数组的结果应该是:Adam(true),John(false)

因此,我需要返回用户的最新条目列表,在这种情况下,约翰首先确认他正在参加,然后他改变主意并告诉他他没有参加,所以我将返回他的最后一个条目(请注意,有时它写的是JOHN有时约翰,但它是同一个人,这是一个棘手的部分)

我的问题是什么是过滤掉这种列表的最佳方法,我正在考虑应用"属性java流的唯一",但首先需要按日期降序和名称(大写/小写)订购人员然后我需要某种方式采取最新的进入.

任何人都知道什么是最好的方法?

Nam*_*man 5

您可以使用Collectors.toMap相同的:

List<Person> finalList = new ArrayList<>(people.stream()
        .collect(Collectors.toMap(a -> a.getName().toLowerCase(),  // name in lowercase as the key of the map (uniqueness)
                Function.identity(), // corresponding Person as value
                (person, person2) -> person.getDate().isAfter(person2.getDate()) ? person : person2)) // merge in case of same name based on which date is after the other
        .values()); // fetch the values
Run Code Online (Sandbox Code Playgroud)

注意:以上假定最小Person

class Person {
    String name;
    java.time.LocalDate date;
    boolean attend;
    // getters and setters
}
Run Code Online (Sandbox Code Playgroud)


Ous*_* D. 5

您可以使用toMap收集器:

Collection<Person> values = source.stream()
                    .collect(toMap(e -> e.getName().toLowerCase(),
                            Function.identity(),
                            BinaryOperator.maxBy(Comparator.comparing(Person::getDate))))
                    .values();
Run Code Online (Sandbox Code Playgroud)

有关 toMap 如何工作的解释,请参阅此答案