Good way to filter list distincted by property and ordered by date

java 8 stream distinct by multiple properties
java list distinct by property
guava distinct by property
java 8 find duplicate objects from list
java filter list of objects by property
java distinct list
java map distinct values
get distinct values from list of objects java

I have very simple thing to do, i have list of persons like this:

[{
    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
}]

Result of this array should be: Adam (true), John (false)

So i need to return list of latest entries from users, in this case John first confirmed that he is attending, then he changed his mind and told that he is not attending so i'm returning his last entry (note that sometimes it's written JOHN and sometimes John but it is the same person, that is kind of tricky part)

My question what is best approach to filter out this kind of list, i was thinking applying "unique by property java stream" but first will need to order persons by date descending and names (to upper/lower case) and then i would need somehow to take latest entry.

Anyone have any good idea what is best approach to this ?

You can use Collectors.toMap to do the same as:

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

Note: The above assumes the minimal Person class to be

class Person {
    String name;
    java.time.LocalDate date;
    boolean attend;
    // getters and setters
}

Filter unique values and sort based on adjacent date, Laura,. you are right, it does not work. I don´t have a solution for you. Mukesh says  @DanielEarwicker this question is about "distinct by property". It would require the stream to be sorted by the same property, to be able to take advantage of it. First, the OP did never state that the stream is sorted at all. Second, streams are not able to detect whether they are sorted by a certain property. Third, there is no genuine

You could use the toMap collector:

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

see this answer for an explanation as to how toMap works

DistinctBy in Java Stream API, Learn about various approaches to searching for distinct list elements in to filtering a collection using a particular attribute of objects in the list. 2. Using the Stream API. The Stream API provides the distinct() method that returns different Really good article with smart solutions, thanks for your hardwork. 0. SELECT DISTINCT(user_id) user_id, created_at FROM creations ORDER BY created_at LIMIT 20 I need the user_id to be DISTINCT , but don't care whether the created_at date is unique or not. Because the created_at date is being included in the evaluation, I am getting duplicate user_id in my result set.

Despite all answers until now are functionally correct, please consider this option:

final Map<String, Boolean> lastAttendResults =
            people
                .stream()
                .collect(
                    groupingBy(
                        Person::getName, // Define what is the property you are using to group people.
                        () -> new TreeMap<String, Boolean>(String.CASE_INSENSITIVE_ORDER), // Supply a map implementation that ignore name case.
                        collectingAndThen(maxBy(Comparator.comparing(Person::getDate)), // Foreach list of grouped people, select that with last date.
                            o -> o.get().isAttend()))); // As maxBy returns an Optional<Person> and we are sure that it exists, just get the Person and if he attends.

This implementation is interesting because it let be evident the concept of collection grouping. Although, in depth, it also uses a map, seems to me that use or not a map is not programmer problem, I mean, what we are looking for is how to group people by name and then get the last entry.

If you prefer receive a List of Person instead of a Map of name and attend, you can use:

final List<Person> lastAttendResults =
        new ArrayList<>(people
            .stream()
            .collect(
                groupingBy(Person::getName, // Define what is the property you are using to group people.
                    () -> new TreeMap<String, Person>(String.CASE_INSENSITIVE_ORDER), // Supply a map implementation that ignore name case.
                    collectingAndThen(maxBy(Comparator.comparing(Person::getDate)), // Foreach list of grouped people, select that with last date.
                        Optional::get // As maxBy returns an Optional<Person> and we are sure that is exists, just get the Person.
                        ))).values());

Java Stream Distinct Examples, Using Java 8 stream API, you can use stream.distinct() method to filter or we will find all distinct strings, collect them into another list using collect() which is java till date, Java does not have any native API for filtering distinct by object property Best Way to Learn Java · Java Best Practices Guide · Microservices Tutorial  I have a collection: List<Car> cars = new List<Car>(); Cars are uniquely identified by their property CarCode. I have three cars in the collection, and two with identical CarCodes.

A compact way without streams:

Map<String, User> map = new LinkedHashMap<>();
users.forEach(u -> map.merge(
        u.getName().toLowerCase(), 
        u, 
        BinaryOperator.maxBy(Comparator.comparing(Person::getDate))));

Collection<User> result = map.values();

Or if you do need a List:

List<User> result = new ArrayList<>(map.values());

This code uses Map.merge, which puts the entry in the map if there's no entry with the same key (the lowercased user name), or, if the map already contains an entry for the key, it applies the merge function, which in this case chooses the User instance with the max date.

Expert Access 2007 Programming, When you click a label, the sort order of the report should be changed to match In this example, you'll add list boxes to a report that will allow the user to filter a report. Set the Record Source property of the report to the following SQL statement: [Ship City]FROM Employees INNER JOIN (Customers RIGHT JOIN Orders  Well, that is about all there is to selecting unique objects from a list. There are three ways to do this: use the Get-Unique cmdlet, use the Unique parameter from the Sort-Object cmdlet, or use the Unique parameter from the Select-Object cmdlet. I invite you to follow me on Twitter and Facebook.

Excel Sorted Dynamic Unique List • My Online Training Hub, Excel Sorted Dynamic Unique Lists have never been so easy now that That way when new rows are added, or rows removed, the formula will FILTER the Names column of Table1 and return a list of values, With the DATE and WEEKDAY functions we can easily list first Monday date in each month. REST API Design: Filtering, Sorting, and Pagination API design is becoming a core pillar of API product strategy regardless if the API is public or used internally. Good API design improves the overall Developer Experience (DX) for any API program and can improve performance and long term maintainability.

Java Stream distinct() Function to Remove Duplicates, Java Stream distinct() method returns a new stream of distinct elements. So it's necessary that the stream elements have proper implementation of equals() method. Using distinct() with an ordered parallel stream can have poor performance jshell> List<Integer> list = List.of(1, 2, 3, 4, 3, 2, 1); list ==> [1, 2, 3, 4, 3, 2,  On your computer, open a spreadsheet in Google Sheets. Select a range of cells. Click Data Create a filter. To see filter options, go to the top of the range and click Filter . Sort by color:

10 Examples of Stream in Java 8, 10 Examples of Stream in Java 8 - count + filter + map + distinct + collect like lambda expression, method reference, new Date and Time classes, and, more In my opinion, the best way to learn any new feature or functionality is by writing isEmpty()) .count(); System.out.printf("List %s has %d empty strings %n", strList,​  Filter unique values and sort based on adjacent date Author: Oscar Cronquist Article last updated on November 26, 2018 The formula in cell F3 extracts unique values from column C, the formula in cell F3 extracts the corresponding dates from column B.

Comments
  • Tip: Format date strings using the standard ISO 8601 format: YYYY-MM-DD. These formats are designed expressly for data exchange, and avoid ambiguity, making them easy for machines to parse and easy for humans to read across cultures. These formats are used by default in the java.time classes when parsing/generating text.
  • Yea, format is already like that, but i made mistake when i wrote it, anyway it is not important in this case at all, but thank you for suggestion
  • The only answer where the grouping has no hidden dependency on the default locale - toLowerCase() uses the default locale, which may yield surprising results, while CASE_INSENSITIVE_ORDER does not take locale into account. It's also easy to replace it with a Collator if necessary.