O que entendi é que ambos retornarão o primeiro elemento correspondente do fluxo, por exemplo, quando usado em conjunto com o filtro?
Isso não é verdade. De acordo com o javadoc, Stream#findAny()
:
Retorna um que Optional<T>
descreve algum elemento do fluxo, ou um vazio
Optional<T>
se o fluxo está vazio. O comportamento dessa operação é explicitamente não determinístico; é grátis selecionar qualquer elemento no stream. Isso é para permitir desempenho máximo em operações paralelas;
while Stream.findFirst()
retornará um Optional<T>
descrevendo estritamente o primeiro elemento do fluxo. A Stream
classe não tem um .findOne()
método, então suponho que você quis dizer .findFirst()
.
filter
aplicado um,findAny
consegue retornar algum elemento, inclusive que não corresponda ao filtro aplicado?findAny
pode retornar qualquer elemento daquele em (mais ou menos) aleatório, particularmente em operações de fluxo paraleloNão, ambos não retornarão o primeiro elemento do Stream.
De
Stream.findAny()
(ênfase minha):O comportamento dessa operação é explicitamente não determinístico; é grátis selecionar qualquer elemento no stream . Isso é para permitir o desempenho máximo em operações paralelas; o custo é que várias invocações na mesma fonte podem não retornar o mesmo resultado. (Se desejar um resultado estável, use em seu
findFirst()
lugar.)Então, para simplificar, ele pode ou não escolher o primeiro elemento do Fluxo.
Com a implementação atual específica do Oracle, acredito que ela retornará o primeiro elemento em um pipeline não paralelo. No entanto, em um pipeline paralelo, nem sempre, executando por exemplo
System.out.println(IntStream.range(0, 100).parallel().findAny());
ele retornou
OptionalInt[50]
quando eu o executei. De qualquer forma, você não deve confiar nisso.fonte
findFirst retorna os primeiros elementos do fluxo, mas findAny é livre para selecionar qualquer elemento no fluxo.
List<String> lst1 = Arrays.asList("Jhonny", "David", "Jack", "Duke", "Jill","Dany","Julia","Jenish","Divya"); List<String> lst2 = Arrays.asList("Jhonny", "David", "Jack", "Duke", "Jill","Dany","Julia","Jenish","Divya"); Optional<String> findFirst = lst1.parallelStream().filter(s -> s.startsWith("D")).findFirst(); Optional<String> fidnAny = lst2.parallelStream().filter(s -> s.startsWith("J")).findAny(); System.out.println(findFirst.get()); //Always print David System.out.println(fidnAny.get()); //Print Jack/Jill/Julia :behavior of this operation is explicitly nondeterministic
fonte
no modo paralelo, o
findAny
não garante a ordem, masfindFirst
sim.Eu escrevi um trecho de código para mostrar a diferença, visite-o
fonte
No stream findFirst e findAny retornam o primeiro elemento e não executam o resto, mas no parallelStream, não é passível dizer a ordem e o parallelStream executa o resto da coleção.
Referência
Hora 1:25:00
fonte
Direi apenas que cuidado com
findFirst()
EfindAny()
ao usar.A partir de seu Javadoc ( aqui e aqui ), os dois métodos retornam um elemento arbitrário do fluxo - a menos que o fluxo tenha uma ordem de encontro , caso em que
findFirst()
retorna o primeiro elemento enquantofindAny()
retornará qualquer elemento.Suponha que temos o
list
ISBN e o nome do LIVRO personalizados. Para um cenário, veja este exemplo:public class Solution { private Integer ISBN; private String BookName; public Solution(int i, String string) { ISBN =i; BookName = string; } //getters and setters }
public static void main(String[] args) { List<Solution> Library = Arrays.asList(new Solution(12,"Java in Action"),new Solution(13,"Java 8"),new Solution(15,"Java 8 Features"),new Solution(16,"Java in Action")); System.out.println(Library.stream() .map(p->p.getBookName()) .sorted(Comparator.reverseOrder()) .findFirst()); }
Produto :
Optional[Java in Action]
Pode haver situações em que o nome do livro é o mesmo, mas os números ISBN são diferentes; nesse caso, a classificação e a localização do livro podem ser muito semelhantes
findAny()
e darão resultados errados. Pense em um cenário onde 5 livros são chamados de "Referência Java", mas têm números ISBN diferentes e ofindFirst()
livro por nome resultará no mesmo quefindAny()
.Pense em um cenário onde:
ISBN Name Of book +-----+------------------+ | 100 | Java-8 in Action | +-----+------------------+ | 101 | Java-8 in Action | +-----+------------------+ | 102 | Java-8 in Action | +-----+------------------+ | 103 | Java-8 in Action | +-----+------------------+ | 104 | Java-8 in Action | +-----+------------------+
aqui findFirst () e findAny () fornecerão o mesmo resultado, mesmo se classificados em BookByName.
Artigo detalhado:
fonte
Quando
Stream
está desordenadofindFirst()
efindAny()
são iguais. Mas quandoStream
for encomendado,findAny()
será melhor.fonte
Stream
ser "ordenado"? É sempre ordenado (as operações são executadas naStream
mesma ordem sempre que não está paralelizado), mas talvez não seja classificado pelo usuário.