Playing with Java 8 Stream from Scala 2.11.5
// $ scala-2.11.5 -Xexperimental
// Original Java 8 version: http://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/
scala> import java.util.{Arrays, List, ArrayList}
scala> import java.util.stream.{Stream, IntStream}
// List<String> myList = Arrays.asList("a1", "a2", "b1", "c2", "c1");
scala> val myList = Arrays.asList("a1", "a2", "b1", "c2", "c1")
myList: java.util.List[String] = [a1, a2, b1, c2, c1]
/*
myList
.stream()
.filter(s -> s.startsWith("c"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);
*/
scala> myList.stream.filter(s => s.startsWith("c")).map(_.toUpperCase).sorted.forEach(println)
C1
C2
/*
Arrays.asList("a1", "a2", "a3")
.stream()
.findFirst()
.ifPresent(System.out::println); // a1
*/
scala> Arrays.asList("a1", "a2", "a3").stream.findFirst.ifPresent(println)
a1
/*
Stream.of("a1", "a2", "a3")
.findFirst()
.ifPresent(System.out::println); // a1
*/
scala> Stream.of("a1", "a2", "a3").findFirst.ifPresent(println)
a1
/*
IntStream.range(1, 4)
.forEach(System.out::println);
*/
scala> IntStream.range(1, 4).forEach(println)
1
2
3
/*
Arrays.stream(new int[] {1, 2, 3})
.map(n -> 2 * n + 1)
.average()
.ifPresent(System.out::println); // 5.0
*/
scala> Arrays.stream(Array(1, 2, 3)).map(n => 2 * n + 1).average.ifPresent(println)
5.0
/*
Stream.of("a1", "a2", "a3")
.map(s -> s.substring(1))
.mapToInt(Integer::parseInt)
.max()
.ifPresent(System.out::println); // 3
*/
// need explicit type arg
scala> Stream.of("a1", "a2", "a3").map(_.substring(1)).mapToInt(Integer.parseInt).max.ifPresent(println)
3
/*
IntStream.range(1, 4)
.mapToObj(i -> "a" + i)
.forEach(System.out::println);
*/
scala> IntStream.range(1, 4).mapToObj(i => "a" + i).forEach(println)
a1
a2
a3
/*
Stream.of(1.0, 2.0, 3.0)
.mapToInt(Double::intValue)
.mapToObj(i -> "a" + i)
.forEach(System.out::println);
*/
scala> Stream.of(1.0, 2.0, 3.0).mapToInt(_.intValue).mapToObj(i => "a" + i).forEach(println)
a1
a2
a3
/*
Stream.of("d2", "a2", "b1", "b3", "c")
.filter(s -> {
System.out.println("filter: " + s);
return true;
});
*/
scala> Stream.of("d2", "a2", "b1", "b3", "c").filter{ s => println(s"filter: $s"); true }
res9: java.util.stream.Stream[String] = java.util.stream.ReferencePipeline$2@4648ce9
scala> .forEach{s => println(s"forEach: $s")}
filter: d2
forEach: d2
filter: a2
forEach: a2
filter: b1
forEach: b1
filter: b3
forEach: b3
filter: c
forEach: c
/*
Stream.of("d2", "a2", "b1", "b3", "c")
.map(s -> {
System.out.println("map: " + s);
return s.toUpperCase();
})
.anyMatch(s -> {
System.out.println("anyMatch: " + s);
return s.startsWith("A");
});
*/
// TODO: type annot
scala> Stream of ("d2", "a2", "b1", "b3", "c") map[String] { s =>
| println(s"map: $s")
| s.toUpperCase
| } anyMatch { s =>
| println(s"anyMatch: $s")
| s.startsWith("A")
| }
/*
Stream.of("d2", "a2", "b1", "b3", "c")
.filter(s -> {
System.out.println("filter: " + s);
return s.startsWith("a");
})
.sorted((s1, s2) -> {
System.out.printf("sort: %s; %s\n", s1, s2);
return s1.compareTo(s2);
})
.map(s -> {
System.out.println("map: " + s);
return s.toUpperCase();
})
.forEach(s -> System.out.println("forEach: " + s));
*/
scala> Stream of ("d2", "a2", "b1", "b3", "c") filter { s =>
| println("filter: " + s)
| s.startsWith("a")
| } sorted { (s1, s2) =>
| println(f"sort: $s1%s; $s2%s\n")
| s1.compareTo(s2)
| } map { s =>
| println("map: " + s)
| s.toUpperCase
| } forEach { s =>
| println("forEach: " + s)
| }
filter: d2
filter: a2
filter: b1
filter: b3
filter: c
map: a2
forEach: A2
/**
class Foo {
String name;
List<Bar> bars = new ArrayList<>();
Foo(String name) {
this.name = name;
}
}
class Bar {
String name;
Bar(String name) {
this.name = name;
}
}
*/
scala> case class Bar(name: String)
defined class Bar
scala> class Foo(val name: String, val bars: List[Bar] = new ArrayList())
defined class Foo
/*
List<Foo> foos = new ArrayList<>();
// create foos
IntStream
.range(1, 4)
.forEach(i -> foos.add(new Foo("Foo" + i)));
// create bars
foos.forEach(f ->
IntStream
.range(1, 4)
.forEach(i -> f.bars.add(new Bar("Bar" + i + " <- " + f.name))));
*/
scala> val foos = new ArrayList[Foo]()
foos: java.util.ArrayList[Foo] = []
// create foos
scala> IntStream.range(1, 4).forEach(i => foos.add(new Foo("Foo" + i)))
// create bars
scala> foos forEach (f =>
| IntStream.range(1, 4) forEach (i =>
| f.bars.add(Bar(s"Bar$i <- ${f.name}")))
| )
/*
foos.stream()
.flatMap(f -> f.bars.stream())
.forEach(b -> System.out.println(b.name));
*/
scala> foos.stream flatMap (_.bars.stream) forEach (b => println(b.name))
Bar1 <- Foo1
Bar2 <- Foo1
Bar3 <- Foo1
Bar1 <- Foo2
Bar2 <- Foo2
Bar3 <- Foo2
Bar1 <- Foo3
Bar2 <- Foo3
Bar3 <- Foo3
// IntStream.range(1, 4)
// .mapToObj(i -> new Foo("Foo" + i))
// .peek(f -> IntStream.range(1, 4)
// .mapToObj(i -> new Bar("Bar" + i + " <- " f.name))
// .forEach(f.bars::add))
// .flatMap(f -> f.bars.stream())
// .forEach(b -> System.out.println(b.name));
// IntStream.range(1, 4).
// mapToObj(i => new Foo("Foo" + i)).
// peek(f => IntStream.range(1, 4).mapToObj(i => new Bar(s"Bar$i <- ${f.name}")).forEach(f.bars.add)).
// flatMap(_.bars.stream).
// forEach(b => println(b.name))
// class Outer { Nested nested; }
// class Nested { Inner inner; }
// class Inner { String foo; }
class Outer(var nested: Nested = null)
class Nested(var inner: Inner)
class Inner(var foo: String)
// Optional.of(new Outer())
// .flatMap(o -> Optional.ofNullable(o.nested))
// .flatMap(n -> Optional.ofNullable(n.inner))
// .flatMap(i -> Optional.ofNullable(i.foo))
// .ifPresent(System.out::println);
Optional.of(new Outer()).
flatMap(o => Optional.ofNullable(o.nested)).
flatMap(n => Optional.ofNullable(n.inner)).
flatMap(i => Optional.ofNullable(i.foo)).
ifPresent(println)
val none = new Outer()
val some = new Outer(new Nested(new Inner("foo")))
for {
o <- Option(some)
n <- Option(o.nested)
i <- Option(n.inner)
foo <- Option(i.foo)
} println(foo)