Encontrar um objeto com o valor mais baixo e devolver o objeto, não o valor, com um fluxo de
-
21-12-2019 - |
Pergunta
Eu, atualmente, encontrar o objeto com o valor mais baixo como este:
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;
}
}
}
onde getScore é:
double getScore(Location loc, RGB colour, boolean average)
Isso é muito lenta, considerando locais geralmente tem alguns milhares de entradas e este ciclo é utilizado alguns milhões de vezes em uma linha.
Então eu queria tentar usar o novo parallelStream() do java 8.Eu fiz um comparador que compara getScore valores.
Location best = locations.parallelStream().min(new ComparatorScoreDif(colour)).get();
Eu estou indo na direção certa, aqui, é esta a maneira correta de fazer isso?
Solução
Location best = locations.parallelStream().min(new ComparatorScoreDif(colour)).get();
Que vai retornar o objeto real do objeto opcional.ele existe.Você pode chamar de .isPresent()
no opcional objeto de antemão para verificar isso.
Eu estou indo na direção certa, aqui, é esta a maneira correta de fazer isso?
Sim, ele é.Chamando .parallelStream()
você mão sobre a simultaneidade parte para a JVM (ele vai particionar o fluxo em vários substreamse você pode centrar-se na própria lógica que tem que ser executadas em paralelo.
Ver OracleDocs - Paralelismo para mais informações e alguns bons explainings.
Outras dicas
Sim, usando min()
com um Comparator
é a abordagem certa para fazer isso.No entanto, você não precisa criar o seu próprio comparador de implementação ComparatorScoreDif
.Em vez disso, você pode usar o Comparator.comparing
combinator função para gerar uma Comparator
, dada uma função que deriva os valores a serem comparados.
Mais exemplos de uso do método de referências para getters sobre o objeto a ser comparado.Se Location
tinha um getScore
o método, seria de fazer isso:
Location best = locations.parallelStream()
.min(Comparator.comparing(Location::getScore))
.get();
No entanto, getScore
não é um método em Location
, e demora alguns parâmetros adicionais.Isso vai exigir escrever uma expressão lambda "longhand" em vez de usar um método de referência.Os valores adicionais podem ser captado do ambiente:
Location best = locations.parallelStream()
.min(Comparator.comparingDouble(loc -> getScore(loc, colour, average)))
.get();
Isto evita a necessidade de escrever uma classe para implementar Comparator
.