-2

Lets consider I have two lists

List1:

[{
“problem”: “prb1",
“status”: “ACTIVE”,
“createTs”: “somedate-1"
}]

List 2:

[{
“problem”: “prb1",
“status”: “ACTIVE”,
“date”: “somedate-1"
},
{
“problem”: “prb1",
“status”: “ACTIVE”,
“date”: “somedate-2"
}]

I want to see if there is an ACTIVE problem in the list2 that doesn't exist as ACTIVE in the list1.

I tried below which is not covering duplicate entry(above scenario)

   list2.removeAll(list1);
             activeprob =
            list2
            .stream()
            .filter(Objects::nonNull)
            .filter(list -> list.getStatus().equals("ACTIVE"))
            .collect(Collectors.toList());

In other way I want to eliminate the duplicate entry in list2 comparing with list1 based on status and date. having same problem is not a concern but should be unique in terms of date.

Please share your insights

happytohelp
  • 305
  • 3
  • 14
  • this may help https://stackoverflow.com/questions/23699371/java-8-distinct-by-property – sanjeevRm Mar 30 '21 at 05:13
  • Hi Surendra, Maybe you need to provide a custom `equals()` method for your schema class. By default, the equals() method looks to see if the objects are the same memory address. But I think you want your equals() method to compare the three fields in one schema object to each schema other. Good luck! – devdanke Mar 30 '21 at 09:50
  • @devdanke Thanks for your response !! Can you please elaborate with some code snippet – Surendra Batreddy Mar 30 '21 at 10:12

2 Answers2

0

What I would suggest doing is

  1. Define hashCode and equals methods for the Problem class (most IDEs can auto generate these methods) if you only want to use the date for equality do that
  2. Convert the List to a Set for improved efficiency, and use the HashSet.contains method
  3. Use a for loop to iterate over the Set. This will allow you to debug the code easier as it is more verbose and you can put a breakpoint in the for loop to see more clearly each step

An example for loop could be

for(Problem p:list2){
   if(list1.contains(p)&&p.status==ACTIVE){
       list2.remove(p);
   }
}

Then list2 should have all duplicates that are ACTIVE removed

  • @rushkin Janowski Thanks for your response!! Consider this is the scenario list1 has old details and list 2 has old and new details. I need to filter out only new details from list2. from above scenario i need to extract only below: List2: ------- { “problem”: “prb1", “status”: “ACTIVE”, “date”: “somedate-2" }] – Surendra Batreddy Mar 30 '21 at 10:15
  • Have you tried using the for loop and stepping through each step using your debugger as I suggested? You can definitely achieve what you want using the for loop as I explained in my answer – Ruskin Janowski Mar 30 '21 at 10:22
0

can you try this, this is going to remove if the active record in list2 is not not active in list1 and same problem name and date. I hope it helps.

list2.removeIf(obj -> {
        List filteredList1 = list1.stream()
                .filter(ob -> obj.getProblem().equals(ob.getProblem())
                        && (!"ACTIVE".equals(ob.getStatus()) && "ACTIVE".equals(obj.getStatus()) )
                        && ob.getDate().equals(obj.getDate()) )
                .collect(Collectors.toList());
        return filteredList1.isEmpty();
    } );

IGNORE from here:
I hope you have almost done, except the small change. I am adding a condition to the filter.

activeprob = list2 .stream() .filter(Objects::nonNull) .filter(list -> list.getStatus().equals("ACTIVE") && notActivelyAvailable(list, list1)) .collect(Collectors.toList());

create a method like this or else you can have this filtered list readily available and can use it directly instead of calling notActivelyAvailable method.

public boolean notActivelyAvailable(YourClass obj, List<YourClass> list1) {
   List<YourClass> filteredList1 = list.stream().filter(yourObj -> "Active".equals(yourObj.getStatus()).collect(Collectors.toList());
if ( filteredList1.contains(obj)) return false;
else return true;
}
krishna thota
  • 182
  • 1
  • 3
  • 8
  • Thank you for your resonse!! Basically in my scenario need to do couple of things: 1) eliminate the entry in "list2" which is matching with "list1" 2)out of filtered list need to filter for list2.getstatus is "ACTIVE" for first step i did as below: list2.removeAll(list1) then applied stream and filter to pick active problem list2.removeAll(list1) --> I think thisis some how not working for all scenarios – Surendra Batreddy Mar 30 '21 at 06:04
  • have you tried executing the code as I suggested and didn't work? – krishna thota Mar 30 '21 at 06:22
  • tried that , i could able to make that happen !! Can you please guide me how to filter the duplicate entries from two lists LIST 1: ---------- [{ “problem”: “prb1", “status”: “ACTIVE”, “createTs”: “somedate-1" }] LIST2: --------- [{ “problem”: “prb1", “status”: “ACTIVE”, “date”: “somedate-1" }, { “problem”: “prb1", “status”: “ACTIVE”, “date”: “somedate-2" }] Filterdlist should have below entry filteredlist : -------------- { “problem”: “prb1", “status”: “ACTIVE”, “date”: “somedate-2" }] – Surendra Batreddy Mar 30 '21 at 07:12
  • list2.retainAll(list1) can get you all duplicated objects only.. – krishna thota Mar 30 '21 at 07:19
  • I need the same in other way , need to exclude those duplicate entries and have distinct entries in list 2 – Surendra Batreddy Mar 30 '21 at 07:24
  • list2.removeAll(list1); used this one , but its not covering all scenarios – Surendra Batreddy Mar 30 '21 at 07:30
  • what is your date format are you considering the time as well? – krishna thota Mar 30 '21 at 07:43
  • I think we missed that date part actually, which list is latest list 1 or list 2 – krishna thota Mar 30 '21 at 07:45
  • Giving details for more clarification: List1: ------- { "problem": "NOSTOCK", "status": "ACTIVE", "UserId": "surendra", "date": "2021-03-29T10:02:38.496354200Z" } – Surendra Batreddy Mar 30 '21 at 08:12
  • list2: ------ { "problem": "NOSTOCK", "status": "ACTIVE", "UserId": "surendra", "date": "2021-03-29T10:02:38.496354200Z" }, { "problem": "OUT_OF_STOCK", "status": "ACTIVE", "UserId": "surendra", "date": "2021-03-30T10:02:38.496354200Z" } – Surendra Batreddy Mar 30 '21 at 08:13
  • onsider this is the scenario list1 has old details and list 2 has old and new details. I need to filter out only new details from list2. from above scenario i need to extract only below: filterList: ------------ { "problem": "OUT_OF_STOCK", "status": "ACTIVE", "UserId": "surendra", "date": "2021-03-30T10:02:38.496354200Z" } – Surendra Batreddy Mar 30 '21 at 08:13
  • list2.removeIf(obj -> { List filteredList1 = list1.stream() .filter(ob -> obj.getProblem().equals(ob.getProblem()) && (!"ACTIVE".equals(ob.getStatus()) && "ACTIVE".equals(obj.getStatus()) ) && ob.getDate().equals(obj.getDate()) ) .collect(Collectors.toList()); return filteredList1.isEmpty(); } ); – krishna thota Mar 30 '21 at 10:10