Reputation: 426
I currently find the object with the lowest value like this:
List<Location> locations = new ArrayList<Location>();
RGB colour = new RGB(5,3,7);
Location best = null;
double bestscore = 0.0;
for(Location loc : locations)
{
if(best == null)
{
best = loc;
bestscore = getScore(loc,colour, average);
}
else
{
double oscore = getScore(loc,colour, average);
if(oscore < bestscore)
{
best = loc;
bestscore = oscore;
}
}
}
where getScore is:
double getScore(Location loc, RGB colour, boolean average)
This is pretty slow considering locations usually has a few thousand entries and this loop is used a few million times in a row.
So I wanted to try and use the new parallelStream() from java 8. I made a comparator that compares getScore values.
Location best = locations.parallelStream().min(new ComparatorScoreDif(colour)).get();
Am I going in the right direction here, is this the right way to do this?
Upvotes: 2
Views: 614
Reputation: 132460
Yes, using min()
with a Comparator
is the right approach to do this. However, you don't need to create your own comparator implementation ComparatorScoreDif
. Instead, you can use the Comparator.comparing
combinator function to generate a Comparator
, given a function that derives the values to be compared.
Most examples use method references to getters on the object being compared. If Location
had a getScore
method, one would do this:
Location best = locations.parallelStream()
.min(Comparator.comparing(Location::getScore))
.get();
However, getScore
isn't a method on Location
, and it takes some additional parameters. This will require writing out a lambda expression "longhand" instead of using a method reference. The additional values can be captured from the environment:
Location best = locations.parallelStream()
.min(Comparator.comparingDouble(loc -> getScore(loc, colour, average)))
.get();
This avoids the need to write out a class to implement Comparator
.
Upvotes: 4
Reputation: 8386
Location best = locations.parallelStream().min(new ComparatorScoreDif(colour)).get();
That will return the actual object from the optional object. it it exists. You might call .isPresent()
on the optional object beforehand to check this.
Am I going in the right direction here, is this the right way to do this?
Yes it is. By calling .parallelStream()
you hand over the concurrency part to the JVM (it will partition the stream into multiple substreams)and you can focus on the actual logic that has to be executed in parallel.
See OracleDocs - Parallelism for further information and some nice explainings.
Upvotes: 1