streamsupport
は基本的にJavaのStream APIを代替する機能を提供してくれますが、それに留まらずStream API以外のJava8の機能やJava9で追加される機能もバックポートしています。
それら機能について以下紹介していきます。
以下内容については、Mavenを利用することを前提にしています。
また、サンプルはRetrolambda
を組み合わせることを前提にした(ラムダ式を利用した)コードを一部記述しています
streamsupport-atomic
Java標準のjava.util.concurrent.atomic
パッケージに対応する機能群の一部をjava8.util.concurrent.atomic
で提供します。
streamsupport-atomic
を利用する場合はpom.xmlに以下を追記します。
<dependency> <groupId>net.sourceforge.streamsupport</groupId> <artifactId>streamsupport-atomic</artifactId> <version>1.5.2</version> </dependency>
■提供されるクラス群
java8.util.concurrent.atomic
パッケージで以下のクラス群が提供されます
LongAdder
LongAccumulator
DoubleAdder
DoubleAccumulator
■サンプルコード
import java8.util.concurrent.atomic.LongAdder; long[] longArray1 = { 10, 20, 30, 40, 50 }; long[] longArray2 = { 1, 2, 3, 4, 5 }; LongAdder adder = new LongAdder(); LongAdder totalCount = new LongAdder(); for (long value : longArray1) { adder.add(value); totalCount.increment(); } System.out.println("(1) elements count=" + totalCount.sum() + ", sum=" + adder.sum()); adder.reset(); for (long value : longArray2) { adder.add(value); totalCount.increment(); } System.out.println("(2) elements count=" + totalCount.sum() + ", sum=" + adder.sum());
■実行結果
(1) elements count=5, sum=150 (2) elements count=10, sum=15
streamsupport-cfuture
CompletableFuture APIを提供します。
streamsupport-cfuture
を利用する場合はpom.xmlに以下を追記します。
<dependency> <groupId>net.sourceforge.streamsupport</groupId> <artifactId>streamsupport-cfuture</artifactId> <version>1.5.2</version> </dependency>
■提供されるクラス群
java8.util.concurrent
パッケージで以下のクラス群が提供されます
CompletableFuture
CompletionStage
■サンプルコード
あまりいいサンプルコードが書けなかったのでサンプルは省略します(笑)
Java8のjava.util.concurrent.CompletableFuture
とjava.util.concurrent.CompletionStage
に対応したものが提供されます。
streamsupport-literal
Java9で追加予定のJEP 269: Convenience Factory Methods for Collectionsに関するコレクションの生成ファクトリを提供します。
streamsupport-literal
を利用する場合はpom.xmlに以下を追記します。
<dependency> <groupId>net.sourceforge.streamsupport</groupId> <artifactId>streamsupport-literal</artifactId> <version>1.5.2</version> </dependency>
■提供されるクラス群
java8.util
パッケージで以下のクラス群が提供されます(なぜパッケージ名がjava8なのかはよく分かりません)
Lists2
Maps2
Sets2
■(1)サンプルコード(Listの生成)
import java.util.List; import java8.util.Lists2; List<String> list0 = Lists2.of(); List<String> list1 = Lists2.of("value1"); List<String> list2 = Lists2.of("value1", "value2"); List<String> list5 = Lists2.of("value1", "value2", "value3", "value4", "value5"); System.out.println("list0 => " + list0.getClass() + " : size=" + list0.size() + " : " + list0); System.out.println("list1 => " + list1.getClass() + " : size=" + list1.size() + " : " + list1); System.out.println("list2 => " + list2.getClass() + " : size=" + list2.size() + " : " + list2); System.out.println("list5 => " + list5.getClass() + " : size=" + list5.size() + " : " + list5); System.out.println("-------------------------------"); // ImmutableなListが生成されているのでaddしようとすると例外が起きる try { list2.add("value3"); } catch (Exception e) { e.printStackTrace(); }
■(1)実行結果
list0 => class java8.util.ImmutableCollections$List0 : size=0 : [] list1 => class java8.util.ImmutableCollections$List1 : size=1 : [value1] list2 => class java8.util.ImmutableCollections$List2 : size=2 : [value1, value2] list5 => class java8.util.ImmutableCollections$ListN : size=5 : [value1, value2, value3, value4, value5] ------------------------------- java.lang.UnsupportedOperationException at java8.util.ImmutableCollections.uoe(ImmutableCollections.java:75) at java8.util.ImmutableCollections$AbstractImmutableList.add(ImmutableCollections.java:81) at sample.ss.stream.ss.other.Lists2Sample.main(Lists2Sample.java:29)
■(2)サンプルコード(Mapの生成)
import java.util.Map; import java8.util.Maps2; Map<Integer, String> map0 = Maps2.of(); Map<Integer, String> map1 = Maps2.of(1, "value1"); Map<Integer, String> map2 = Maps2.of(10, "value1", 20, "value2"); Map<Integer, String> map3 = Maps2.of(101, "value1", 102, "value2", 103, "value3"); System.out.println("map0 => " + map0.getClass() + " : size=" + map0.size() + " : " + map0); System.out.println("map1 => " + map1.getClass() + " : size=" + map1.size() + " : " + map1); System.out.println("map2 => " + map2.getClass() + " : size=" + map2.size() + " : " + map2); System.out.println("map3 => " + map3.getClass() + " : size=" + map3.size() + " : " + map3); System.out.println("-------------------------------"); // ImmutableなMapが生成されているのでaddしようとすると例外が起きる try { map2.put(30, "value3"); } catch (Exception e) { e.printStackTrace(); }
■(2)実行結果
map0 => class java8.util.ImmutableCollections$Map0 : size=0 : {} map1 => class java8.util.ImmutableCollections$Map1 : size=1 : {1=value1} map2 => class java8.util.ImmutableCollections$MapN : size=2 : {20=value2, 10=value1} map3 => class java8.util.ImmutableCollections$MapN : size=3 : {101=value1, 103=value3, 102=value2} ------------------------------- java.lang.UnsupportedOperationException at java8.util.ImmutableCollections.uoe(ImmutableCollections.java:75) at java8.util.ImmutableCollections$AbstractImmutableMap.put(ImmutableCollections.java:443) at sample.ss.stream.ss.other.Maps2Sample.main(Maps2Sample.java:29)
streamsupport-flow
JDK 9 Flow API(Java 9で導入される予定のReactive Streams向けのpublish-subscribeフレームワーク)を提供してくれます
(JEP 266: More Concurrency Updates)
streamsupport-flow
を利用する場合はpom.xmlに以下を追記します。
<dependency> <groupId>net.sourceforge.streamsupport</groupId> <artifactId>streamsupport-flow</artifactId> <version>1.5.2</version> </dependency>
■提供されるクラス群
java8.util.concurrent
パッケージで以下のクラス群が提供されます(なぜパッケージ名がjava8なのかはよく分かりません)
Flow
Flow.Publisher
Flow.Subscriber
Flow.Subscription
Flow.Processor
SubmissionPublisher
■サンプルコード
import java8.util.concurrent.Flow.Subscriber; import java8.util.concurrent.Flow.Subscription; import java8.util.concurrent.SubmissionPublisher; import java8.util.stream.RefStreams; public class FlowSample { public static void main(String[] args) { SubmissionPublisher<String> publisher = new SubmissionPublisher<>(); //Subscriberの登録 SimpleSubscriber<String> subscriber = new SimpleSubscriber<>(); publisher.subscribe(subscriber); //値の発行 System.out.println("Publishing Items..."); RefStreams.of("1", "###", "2", "###", "3", "###", "4", "###") .forEach(e -> publisher.submit(e)); publisher.close(); } static final class SimpleSubscriber<T> implements Subscriber<T> { private Subscription subscription; @Override public void onSubscribe(Subscription subscription) { this.subscription = subscription; subscription.request(1); } @Override public void onNext(T item) { System.out.println("> OnNext : " + item); subscription.request(1); } @Override public void onError(Throwable t) { System.out.println("On Error: " + t.getMessage()); } @Override public void onComplete() { System.out.println("Complete!!"); } } }
■実行結果
Publishing Items... > OnNext : 1 > OnNext : ### > OnNext : 2 > OnNext : ### > OnNext : 3 > OnNext : ### > OnNext : 4 > OnNext : ### Complete!!
まとめ
streamsupport
はStream APIにとどまらず、Java9の機能にまで及ぶ範囲でバックポートをしてくれていることが分かりました。