1

I have the below working code using one value to compare but want to compare with two values. I need to add one more filter as "getAddressID" along with getAction. Could some help me to modify the below code?

List<Data> finalData = dataList.stream().collect(
    Collectors.collectingAndThen(
        Collectors.toCollection(
            () -> new TreeSet<>(Comparator.comparing(Data::getAction))),
            ArrayList::new))
public class TestCollection {

/**
 * @param args
 */
public static void main(String[] args) {
    
    List<Data> dataList = new ArrayList<Data>();
    
    Data data1 = new Data("DELIVERED", "1112");
    Data data2 = new Data("DELIVERED", "1113");
    Data data3 = new Data("PICKEUP", "1112");
    Data data4 = new Data("PICKEUP", "1112");
    
    dataList.add(data1);
    dataList.add(data2);
    dataList.add(data3);
    dataList.add(data4);
    
    //Filer by Action
    List<Data> finalData = dataList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<> (Comparator.comparing(Data::getAction))), ArrayList::new));
    
    for(Data data : finalData) {
        System.out.println(" Action " + data.getAction() + " Address ID " + data.getAddressID());
    }
    
    

}

}

The result is : "Action DELIVERED Address ID 1112" "Action PICKEUP Address ID 1112"

But I want result as: "DELIVERED Address ID 1112" "DELIVERED Address ID 1113" "PICKEUP Address ID 1112"

6
  • Can you explain a bit more in detail, what your code should do actually? Maybe also add an example of input and desired output. Commented Mar 16, 2022 at 17:11
  • Input is a list of Data objects. Data object has attributes inside of it. Above code is able to filetr by "Action" attrubute and returns a list. I just need to add one more filer to the code. I am going to write a smaple code and post in few minutes. Commented Mar 16, 2022 at 17:15
  • Does your Data class only have the two fields addressID & action or are there more? Are both fields strings like shown in your code or was is just an example? Commented Mar 16, 2022 at 17:59
  • 1
    Have you tried adding a second comparator, ie: Comparator.comparing(Data::getAction).thenComparing(Comparator.comparing(Data::otherMethod) Commented Mar 16, 2022 at 18:15
  • 1
    @Zeke Rogers. That's it. It worked. Thank you so much.Pleas put that as a solution. I will accept it. Commented Mar 16, 2022 at 18:21

2 Answers 2

2

You can chain your comparators using thenComparing, ie

new TreeSet<>(Comparator.comparing(Data::getAction).thenComparing(Comparator.comparing(Data::otherMethod))
Sign up to request clarification or add additional context in comments.

Comments

0

If I get it right, you are trying to get distinct items from your list by the combination of the two properties addressID & action. Here is a an accepted answer, thanks to @Stuart Marks, which works to get distinct elements by one property. That could be further modified to solve your use case like:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;


....

List<Data> dataList = // your data objects

List<Data> distinctData = dataList.stream()
            .filter(distinctByKeys(Data::getAction, Data::getAddressID))
            .collect(Collectors.toList());

where the method distinctByKeys could look like

private static <T> Predicate<T> distinctByKeys(final Function<? super T, ?>... keyExtractors) {
    final Map<List<?>, Boolean> seen = new ConcurrentHashMap<>();
    return t -> {
        final List<?> keys = Arrays.stream(keyExtractors)
                .map(ke -> ke.apply(t))
                .collect(Collectors.toList());
        return seen.putIfAbsent(keys, Boolean.TRUE) == null;
    };
}

1 Comment

Your answer also look good to me. However, I just want to make a change to the exiting code. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.