0

I recieved a List of Objects from my Data Base and, I would like to remove duplicates with same id except the duplicate which have smallest date, and if the date is equal, I would like to keep the object with the smallest "cxalap" :

For exemple :

If my list from the Data Base is the following :

List<NotificationCnavOP> notificationCnavOPList = [{id = 1; date = 01/01/2000; cxalap= 1}, {id=2; date = 01/01/2001; cxalap = 2}, {id=2, date = 01/01/2002; cxalap=3}, {id=2, date = 01/01/2001; cxalap=2}]

The new filter list will keep the first two :

List<NotificationCnavOP> notificationCnavOPListFiltered = [{id = 1; date = 01/01/2000; cxalap= 1}, {id=2; date = 01/01/2001; cxalap = 2}]

I don't have any idea of methods to use for making this

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
Pelodido3
  • 17
  • 5

1 Answers1

0
  1. Sort your list first on id, then on the date, and then on cxalap.

  2. Merge the sorted list into a Map with id as the key. In case of a conflict, keep the first record and discard others. Since the list is already sorted, this step will ensure that the first record for an id will be kept while others will be discarded. Check Collectors.toMap to learn more about this.

  3. Collect the stream of values of the Map as the final List.

    List<NotificationCnavOP> result=
                    notificationCnavOPList
                    .stream()
                    .sorted(Comparator.comparing(NotificationCnavOP::getId)
                            .thenComparing(e -> LocalDate.parse(e.getDate(), DateTimeFormatter.ofPattern("dd/MM/yyyy")))
                            .thenComparing(NotificationCnavOP::getCxalap))
                    .collect(Collectors.toMap(NotificationCnavOP::getId, Function.identity(), (e1, e2) -> e1))
                    .values()
                    .stream()
                    .collect(Collectors.toList());
    

Demo:

    import java.time.LocalDate;
    import java.time.format.DateTimeFormatter;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Comparator;
    import java.util.List;
    import java.util.function.Function;
    import java.util.stream.Collectors;

    public class Main {
        public static void main(String[] args) throws Exception {
            List<NotificationCnavOP> notificationCnavOPList = new ArrayList<>(
                    Arrays.asList(
                            new NotificationCnavOP(1, "01/01/2000", 1), 
                            new NotificationCnavOP(2, "01/01/2001", 2),
                            new NotificationCnavOP(2, "01/01/2002", 3), 
                            new NotificationCnavOP(2, "01/01/2001", 2)));

            List<NotificationCnavOP> result = 
                    notificationCnavOPList
                    .stream()
                    .sorted(Comparator.comparing(NotificationCnavOP::getId)
                            .thenComparing(e -> LocalDate.parse(e.getDate(), DateTimeFormatter.ofPattern("dd/MM/yyyy")))
                            .thenComparing(NotificationCnavOP::getCxalap))
                    .collect(Collectors.toMap(NotificationCnavOP::getId, Function.identity(), (e1, e2) -> e1))
                    .values()
                    .stream()
                    .collect(Collectors.toList());

            System.out.println(result);
        }
    }

    class NotificationCnavOP {
        private int id;
        private String date;
        private int cxalap;

        public NotificationCnavOP(int id, String date, int cxalap) {
            this.id = id;
            this.date = date;
            this.cxalap = cxalap;
        }

        public int getId() {
            return id;
        }

        public String getDate() {
            return date;
        }

        public int getCxalap() {
            return cxalap;
        }

        @Override
        public String toString() {
            return "[" + id + ", " + date + ", " + cxalap + "]";
        }
    }

Output:

    [[1, 01/01/2000, 1], [2, 01/01/2001, 2]]

ONLINE DEMO

Learn more about the modern Date-Time API* from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • Thank you very much ! But I have a "java.time.format.DateTimeParseException" with the line : .thenComparing(e -> LocalDate.parse(e.getDate(), DateTimeFormatter.ofPattern("dd/MM/yyyy")). Do you know why ? – Pelodido3 Jun 17 '20 at 22:02
  • @Pelodido3 - Did you copy and run my code as it is? – Arvind Kumar Avinash Jun 17 '20 at 22:22
  • 1
    By copying your code entirely, I have an incompatible types : "Date cannot be converted to CharSequence" So I tried to add a .toString() and I had have this error : "java.time.format.DateTimeParseException" – Pelodido3 Jun 18 '20 at 08:47
  • @Pelodido3 - It seems you've missed something which I'm not able to guess. The code I have posted is tested. I just tested it again and there is no compilation or runtime error. – Arvind Kumar Avinash Jun 18 '20 at 09:07
  • @Pelodido3 - You might have imported some wrong class(es). I've updated my code with the `import` statements as well. I hope, it helps. – Arvind Kumar Avinash Jun 19 '20 at 13:01