Aqui veremos alguns show cases de utilização da API de stream do Java 8, uma API poderosa para manipulação de coleções
No exemplo a seguir vemos uma simples interação sobre uma lista
List<String> items = Arrays.asList("a","b","c","d","e");
items.stream().forEach( i -> System.out.println( i ) );
items.stream().forEach( System.out::println );
Como pode ver as collections java agora expõe um método stream(), para que você possa usar a API, no exemplo estamos apenas printando cada item, você pode perceber também que podemos fazer isso por uso de lambdas, ou usando o atalho da chamada.
Digamos agora que queremos filtrar nossa lista e recuperar apenas os elementos "a", "b" e "c", a API de stream fornece um método para o mesmo, lembrando apenas que a maioria dos métodos da API retornam novas Streams. Veja a seguir
List<String> items = Arrays.asList("a","b","c","d","e");
items.stream().filter( i -> "a".equals( i ) || "b".equals(i) || "c".equals(i) ).forEach(System.out::println);
Nesse caso se quisermos na verdade coletar esse resultado como uma nova lista, basta usarmos o método collect
List<String> items = Arrays.asList("a","b","c","d","e");
List<String> collect = items.stream()
.filter(i -> "a".equals(i) || "b".equals(i) || "c".equals(i))
.collect(Collectors.toList());
Podemos utilizar também o método map() para manipular o dado da lista, veja a seguir
List<String> items = Arrays.asList("a","b","c","d","e");
List<String> collect = items.stream().map( i -> i + "1" )
.collect(Collectors.toList());
O método map irá iterar sobre cada item, e retorna uma nova stream com as alterações realizadas
Agora vamos tentar fazer algo mais complicado, criaremos uma lista de um objeto complexo User, iremos filtrar pelo nome e em seguida vamos coletar a data de nascimento de cada item ordenando por maior para menor
// Type.java
public enum Type{
SUPER,
NORMAL;
}
// User.java
public class User{
private String name;
private Type type;
private Date birthdate;
private Double contribution;
public User(String name, String surname, String birthdate, Type type, Double contribution) throws ParseException {
this.name = name;
this.type = type;
this.contribution = contribution;
this.birthdate = new SimpleDateFormat("yyyy-MM-dd").parse( birthdate );
}
public String getName() {
return name;
}
public Date getBirthdate() {
return birthdate;
}
public Double getContribution() {
return contribution;
}
public Type getType() {
return type;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", type=" + type +
", birthdate=" + birthdate +
", contribution=" + contribution +
'}';
}
}
List<User> users = Arrays.asList(
new User("user1" , "Test" , "1999-01-01", 0.0)
,new User("user2" , "Loren" , "1980-02-20", 1000.0)
,new User("patty" , "ypsun" , "1992-03-25", 1500.0)
,new User("user3" , "Broken Data" , "1920-03-25", 443.00)
,new User("efras" , "Gentil" , "2000-02-27", 150.00)
);
List<Date> usersBirthDates = users.stream().filter(i -> i.getName().contains("user"))
.map(i -> i.getBirthdate())
.sorted( ( a , b ) -> a.compareTo(b) )
.collect(Collectors.toList());
System.out.println("users = " + usersBirthDates );
Veja que podemos encadear varias chamadas para enfim obtermos nosso resultado, isso torna a API bastante poderosa e fluente
Agora vamos tentar descobrir qual foi a contribuição de todos os usuários que possuem user no nome, para isso usaremos o método reduce()
Double totalContribuinte = users.stream().filter(i -> i.getName().contains("user"))
.map(User::getContribution)
.reduce(0.0, (partial, current) -> {
sout
partial + current
});
O método reduce recebe como primeiro parâmetro o valor inicial para a agregação, em seguida como segundo parâmetros temos uma expressão lambda onde o primeiro parâmetro é o valor parcial das outras interações e o segundo o valor atual da interação.
Podemos também agrupar registros usando collect(), como pode ser visto no exemplo abaixo
Map<Type, List<User>> collect = users.stream().collect(Collectors.groupingBy(User::getType));
collect.entrySet().stream().forEach( e -> System.out.println(e.getKey() + ": " + e.getValue() ) );
Com isso vimos alguns usos basicos da API de stream do Java, você pode estudar mais a fundo no link