Find closest object in Java collection for a given value using Java8 stream

Viewed 750

I want to find a matching or a closest entry from a collection for a given timestamp value.

My collection is List of Object.. which contains name, id, timestamp etc..

String id;
long timestamp;

I want to first match on Id(you can have multiple) and then find the match for a given timestamp or return closest to it from collection. how can i do that?

myList.stream().filter(p -> p.getId().equals(Id))
                .min((f1,f2) -> Math.abs(f1.getTS() - timestamp) - Math.abs(f2.getTS() - timestamp))
                .findfirst().get();

its also having issue with long to int conversion too.

error : type mismatch - cannot convert from long to int.

2 Answers

What you are mixing up are two things, one that the Comparator return type mismatch as evident from the error you get. This could be resolved when you compare two Long values instead of performing a subtraction(-) for comparing.

.min((f1,f2) -> Long.compare(Math.abs(f1.getTS() - timestamp), Math.abs(f2.getTS() - timestamp)))

Then further it could be simplified to

.min(Comparator.comparingLong(f -> Math.abs(f.getTS() - timestamp)))

Another aspect is the mix up of findFirst with min since min itself returns an Optional<T> as the minimum element of the stream. Your solution can therefore be fixed with:

YourClass closest = myList.stream().filter(p -> p.getId().equals(id))
        .min(Comparator.comparingLong(f -> Math.abs(f.getTS() - timestamp)))
        .orElse... // throw exception or choose default value

Try this,

List<User> userList = users.stream()
        .filter(user -> user.getId().equals(ID))
        .sorted(Comparator.comparingLong(user -> Math.abs(TIME - user.getTime())))                                                            
        .collect(Collectors.toList());

userList will be sorted according to nearest TIME (given timestamp) and do get(0)

Related