Erstgespräch vereinbaren
Kommende Termine
4. Mai 2026
IT-Talk: Digitale Verantwortung
Details →
12. Juni 2026
Vernissage
28. September 2026
IT-Talk: Event-Driven Architecture

Java Streams vs Javaslang - funktional arbeiten mit Java 8

Vergleich von Java 8 Streams und Javaslang: Immutable Collections, funktionale Datenverarbeitung und praktische Beispiele.

Nahaufnahme eines Bildschirms mit Code

Funktionale Datenverarbeitung in Java hat sich mit Java 8 verändert. Vor Java 8 griffen Entwickler oft auf Guava für funktionale Operationen zurück. Mit der Einführung von Lambdas und Streams in Java 8 wechselten viele weg von Guava. Allerdings bot Guava unveränderliche Datenstruktur-Implementierungen, während die Java Collections API nicht für Unveränderlichkeit konzipiert wurde, was zu Laufzeit-Überraschungen führt.

Das Javaslang-Projekt geht einen anderen Weg, indem es die Java Collections API vollständig verlässt und eine eigene API mit unveränderlichen Datenstrukturen erstellt. Obwohl es Iterable für die Interaktion mit Java Collections implementiert, zielt es darauf ab, die Collections API komplett zu ersetzen.

Daten aus einer Liste in eine Map transformieren

1:1 Map

Javaslang:

List<Integer> source = List.of(1,2,3,4);
Map<String, Integer> result = source.groupBy(e -> e.toString())
	.mapValues(v -> Iterables.getOnlyElement(v));

Java 8:

Collection<Integer> source = ImmutableList.of(1, 2, 3, 4);
Map<String, Integer> result = source.stream()
		.collect(Collectors.toMap(e -> e.toString(), x -> x));

Javaslang gibt unveränderliche Implementierungen zurück, ohne bei Kollisionen Exceptions zu werfen – anders als Java 8.

Transformation von Schlüssel und Wert

Javaslang:

List<Person> source = List.of(Person.of("Klaus",42),Person.of("Bert",33));
Map<String, Integer> result = source.toMap(e -> Tuple.of(e.name, e.age));

Java 8:

Collection<Person> source = ImmutableList.of(Person.of("Klaus",42),Person.of("Bert",33));
Map<String, Integer> result = source.stream()
		.collect(Collectors.toMap(e -> e.name, e -> e.age));

Werte anhand eines Schlüssels gruppieren

Javaslang:

List<String> source = List.of("Klaus","Klaas","Susi","Jane","Jan","Jochen");
Map<String, List<String>> result = source.groupBy(e -> e.substring(0,1));

Java 8:

Collection<String> source = ImmutableList.of("Klaus","Klaas","Susi","Jane","Jan","Jochen");
Map<String, ? extends Collection<String>> result = source.stream()
		.collect(Collectors.groupingBy(e -> e.substring(0,1)));

Listen aus Listen

Listen filtern und transformieren

Javaslang:

List<Integer> src = List.of(1,2,3,4,5,6,7);
List<String> result = src
	.filter(e -> e % 2 == 0)
	.map(e -> e.toString());

Java 8:

List<Integer> src = Lists.newArrayList(1,2,3,4,5,6,7);
Collection<String> result = src.stream()
	.filter(e -> e % 2 == 0)
	.map(e -> e.toString())
	.collect(Collectors.toList());

Der wesentliche Unterschied: Javaslang liefert Zwischenergebnisse als unveränderliche Objekte ohne terminale Operationen, während Streams eine finale Collection erfordern.

Flatmap - ein Universalwerkzeug

Das Konzept kombiniert die Elementtransformation in Listen mit anschließender Verkettung. Anwendungsfälle umfassen:

  • Leere Ergebnislisten
  • Einelementige Listen
  • Mehrelementige Listen

Listen aneinander hängen

Javaslang:

List<List<String>> src = List.of(List.of("A","B","C"), List.of("D","E"), List.of("F","G","H","I","J"), List.of("Z"));
List<String> result = src.flatMap(e -> e);

Java 8:

List<ImmutableList<String>> src = ImmutableList.of(ImmutableList.of("A","B","C"),
	ImmutableList.of("D","E"),
	ImmutableList.of("F","G","H","I","J"),
	ImmutableList.of("Z"));
List<String> result = src.stream()
		.flatMap(e -> e.stream())
		.collect(Collectors.toList());

Javaslang in Action

String result = List.of("Susi","Sara","Jane")
  .zipWithIndex()
  .toMap(t -> Tuple.of(t._2(), t._1()))
  .map(t -> t._1+":"+t._2)
  .foldLeft(null, (l,r) -> l==null ? r : l+" - "+r);

Dieses Beispiel demonstriert Verkettung: eine Liste in indizierte Tupel konvertieren, eine Map erstellen, diese transformieren und zu einem einzelnen String falten.

Zusammenfassung

Während Java Streams sequenzielle Datenverarbeitung effektiv bewältigen, fehlt ihnen die Unterstützung für andere Konstrukte. Javaslang bietet ein umfassendes Toolkit, das besonders wertvoll für seinen standardmäßigen Unveränderlichkeitsansatz ist.

Zurück zum Blog