Java Stream Commands

Published: 2017-10-10, Updated: 2021-05-06

Array de int[] para Set/List/Integer[]

Integer[] boxedArray = IntStream.of(new int[]{1,2,3}).boxed().toArray(Integer[]::new);
Set<Integer> set = IntStream.of(new int[]{1,2,3}).boxed().collect(Collectors.toSet());

From List to Map of lists

final var valuesByKey = Stream
    .of(
        new AbstractMap.SimpleEntry<>("A", 1),
        new AbstractMap.SimpleEntry<>("A", 2),
        new AbstractMap.SimpleEntry<>("A", 3),
        new AbstractMap.SimpleEntry<>("B", 1),
        new AbstractMap.SimpleEntry<>("B", 2),
        new AbstractMap.SimpleEntry<>("B", 4)
    )
    .collect(Collectors.groupingBy(AbstractMap.SimpleEntry::getKey));
System.out.println(valuesByKey);
// {A=[A=1, A=2, A=3], B=[B=1, B=2, B=4]}

Map reduce with java

Mapping de 1 -> 1 - List to Map

Map<String, Integer> numbersById = IntStream
    .range(1, 10)
    .boxed()
    .collect(Collectors.toMap(String::valueOf, Function.identity()));
System.out.println(numbersById);
// {1=1, 2=2, 3=3, 4=4, 5=5, 6=6, 7=7, 8=8, 9=9}

Reduce de Map / GroupBy Reducing

Forma 1 - Collectors.toMap
Map<String, Integer> numbersById = Stream
  .of(
      new AbstractMap.SimpleEntry<>("A", 1),
      new AbstractMap.SimpleEntry<>("A", 2),
      new AbstractMap.SimpleEntry<>("A", 3),
      new AbstractMap.SimpleEntry<>("B", 1),
      new AbstractMap.SimpleEntry<>("B", 2),
      new AbstractMap.SimpleEntry<>("B", 4)
  )
  .collect(Collectors.toMap(
      AbstractMap.SimpleEntry::getKey,
      AbstractMap.SimpleEntry::getValue,
      Integer::sum
  ));
System.out.println(numbersById);
// {A=6, B=7}

Forma 2 - Collectors.groupBy / Collectors.reducing com objetos complexos
Stream.of(
    new AbstractMap.SimpleEntry<>("Apple", 1),
    
    new AbstractMap.SimpleEntry<>("Orange", 1),
    new AbstractMap.SimpleEntry<>("Orange", 1),
    
    new AbstractMap.SimpleEntry<>("Grape", 1),
    new AbstractMap.SimpleEntry<>("Grape", 1),
    new AbstractMap.SimpleEntry<>("Grape", 1)
)
.collect(
    Collectors.groupingBy(
        AbstractMap.SimpleEntry::getKey,
        Collectors.reducing(
            new AbstractMap.SimpleEntry<>("", 0),
            (a, b) -> new AbstractMap.SimpleEntry<>(a.getKey(), a.getValue() + b.getValue())
        )
    )
)
.forEach((k, v) -> System.out.printf("k=%s, v=%s%n", k, v.getValue()));
// k=Apple, v=1
// k=Grape, v=3
// k=Orange, v=2
Forma 3 - Collectors.groupBy / Collectors.reducing com inteiros
Stream
  .of(
      "a", "b", "c", "d",
      "c", "f", "g", "a"
  )
  .collect(
      Collectors.groupingBy(
          Function.identity(),
          Collectors.summingInt((it) -> 1)
      )
  )
  .forEach((k, v) -> System.out.printf("%s=%d%n", k, v));
// a=2
// b=1
// c=2
// d=1
// f=1
// g=1

Reduce de Lista

Exemplo 1 - Fazendo com numeros

final var sum = Stream
  .of(1, 2, 3)
  .collect(Collectors.summarizingDouble(Integer::doubleValue))
  .getSum();
System.out.println(sum);
// 6.0

Exemplo 2 - Fazendo com objetos complexos

final var sum = Stream
  .of(
      new AbstractMap.SimpleEntry<>("Orange", 2.50),
      new AbstractMap.SimpleEntry<>("Banana", 1.25)
  )
  .collect(Collectors.summarizingDouble(AbstractMap.SimpleEntry::getValue))
  .getSum();
System.out.println(sum);
// 3.75

Fazer map de lista

Java >6

final List<String> keys = Arrays.asList(new LinkedHashMap<String, String>()).stream().map(map -> {
  return map.get("key");
}).collect(Collectors.toList());

JAVA <6

...
import com.google.common.base.Function;
import com.google.common.collect.Lists;
...

List<String> mails = Lists.transform(message.getAllValues(), new Function<TurnoverAwardMessage, String>() {
  @Override
  public String apply(TurnoverAwardMessage turnoverAwardMessage) {
      return turnoverAwardMessage.getNamLogin();
  }
});

Quando usar parallelstream

Se houverem muitos registros, ex: 10_000_000 ou se o reduce, map, filter for algo pesado então compensa usar o parallel senão nao compensa

Um exemplo de onde compensa o parallelStream, cada mapeamento leva 100ms entao se for parallelizado isso vai ser muito mais rapido

List<Person> persons= new ArrayList<>();
for(int i=0; i < 100; i++){
    persons.add(new Person("User " + i, i));
}

final StopWatch stopWatch = new StopWatch();
stopWatch.start();
final List<Integer> pkeys = persons.parallelStream().map(map -> {
    try {Thread.sleep(100);} catch (Exception e){}
    return map.xp;
}).collect(Collectors.toList());
stopWatch.stop();
System.out.printf("paralleltime=%d%n", stopWatch.getTime());

stopWatch.reset();
stopWatch.start();
final List<Integer> keys = persons.stream().map(map -> {
    try {Thread.sleep(100);} catch (Exception e){}
    return map.xp;
}).collect(Collectors.toList());
stopWatch.stop();
System.out.printf("seqtime=%d%n", stopWatch.getTime());

static class Person {
  String name;
  int xp;

  public Person(String name, int xp) {
      this.name = name;
      this.xp = xp;
  }
}

Stream para Array

String[] stringArray = streamString.toArray(String[]::new);

Criar uma collection customizada

Arrays.asList(1).stream().collect(Collectors.toCollection(() -> new TreeSet()));

ou ...

Comparator<PositionReport> byTimestamp = Comparator.comparingLong(PositionReport::getTimestamp);
Supplier<TreeSet<PositionReport>> supplier = () -> new TreeSet<PositionReport>(byTimestamp);
positionReports.stream()
	.filter(p -> p.getTimeStamp() >= oldestKept)
	.collect(Collectors.toCollection(supplier));

Interseção

final var a = List.of(1, 2, 3);
final var b = List.of(1, 2);

{
  final var tmp = new ArrayList<>(a);
  tmp.retainAll(b);
  System.out.println(tmp);
}
{
  final var tmp = new ArrayList<>(b);
  tmp.retainAll(a);
  System.out.println(tmp);
}
// [1, 2]
// [1, 2]

keywords

java commands, java streams


ActiveMQ (Artemis) Vs RabbitMQ, what's the best? Fixing Corrupted FileSystem in Linux

Comments