Java(1.8)高度なプロパティ-フロー
8071 ワード
流れとは
ファイルの入出力ストリームに関係なく、ストリーム(Stream)は類似の集合の概念です.ストリームによって集合に対して「何をするか」を定義することで、目標を達成することができます.
フローの操作方法
ストリームを使用して目的を達成するには、3つのステップが必要です.ストリーム を作成する変換ストリーム(初期ストリームを定義する「何をするか」によって他のストリームに変換する) 終端動作(terminal peration、最終ストリームから必要なデータを取得) 次に、
フローの作成
きりかえりゅう
これは3つの主要なストリーム変換方法である. filter map flatmap
以上の3つの方法に加えて、
終了操作
ストリームを定義して変換した後、私たちはやっと私たちが望んでいるデータを得ることができます.
もちろん,変換後のストリームは必ずしも上述した終端操作を行う必要はなく,得られた結果を集合に格納して用いることもできる.
へいれつりゅう
パラレルストリームを作成して、ストリームの処理速度を速めることができます.ストリームを取得する方法には、
ファイルの入出力ストリームに関係なく、ストリーム(Stream)は類似の集合の概念です.ストリームによって集合に対して「何をするか」を定義することで、目標を達成することができます.
フローの操作方法
ストリームを使用して目的を達成するには、3つのステップが必要です.
Integer
のタイプのストリームを作成し、ストリーム内のすべての要素に対してx=x+1
のメソッドを呼び出し、最後にreduce
を使用して動作を終了してストリーム全体の和を得る例を示す.ストリームの操作は、結果が必要になるまで可能な限り不活性に実行されます.すなわち、終了操作が適用されると、以前の不活性操作が強制的に実行され、ストリームは機能しません.Stream s=Stream.of(1,2,3,4);
int sum=s.map(x->x+1).reduce(0,(x,y)->{x+y});
フローの作成
//
public static Stream of(T t)
// ,
public static Stream of(T... values)
//
public static Stream empty()
// , seed,f(seed),f(f(seed)),....
// :Stream s=Stream.iterate(1,x->x+1);
public static Stream iterate(final T seed, final UnaryOperator f)
// Supplier
// :Stream s=Stream.generate(Math::random)
public static Stream generate(Supplier s)
Stream
クラスでは、上記の方法でストリームを作成できます.このほか、Arrays
、コレクションクラス、Files
もストリームを作成する方法を提供しています.//
public static Stream stream(T[] array, int startInclusive, int endExclusive)
//
default Stream stream()
// ,
public static Stream lines(Path path, Charset cs) throws IOException
きりかえりゅう
Stream
は、変換ストリームを行うための様々な方法を提供する.Stream filter(Predicate super T> predicate);
Stream map(Function super T, ? extends R> mapper);
Stream flatMap(Function super T, ? extends Stream extends R>> mapper);
これは3つの主要なストリーム変換方法である.
filter
の引数はPredicate、すなわちTからbooleanまでの関数であり、この方法を用いて条件を満たすストリームを得ることができ、例えばStream s=Stream.of(1,2,3,4,5).filter(x->x>3)
を介して3より大きいストリームを得ることができる.map
は、Stream
の各要素に対してmapper
メソッドを呼び出し、例えばStream s=Stream.of(1,2,3,4,5).map(x->x=x+1)
は各要素に1つのストリームを加えることができる.flatmap
は、処理後に得られるStream>
をStream
のストリームに均等に割り当てることができる.例えば、Stream.of("apple","bit").map(x->letters(x))
は[["a","p","p","l","e"],["b","i","t"]]
を得、Stream.of("apple","bit").flatmap(x->letters(x))
は["a","p","p","l","e","b","i","t"]
を得る.以上の3つの方法に加えて、
Stream
クラスは、サブストリームの取得、ソートなどの方法を提供する.// maxSize
Stream limit(long maxSize);
// n
Stream skip(long n);
//
public static Stream concat(Stream extends T> a, Stream extends T> b) ;
//
Stream sorted();
Stream sorted(Comparator super T> comparator);
//
Stream distinct();
// action , debug
// :Stream.of(1,2,3,4).peek(x->System.out.print(x)).map(x->x=x+1)
Stream peek(Consumer super T> action);
終了操作
ストリームを定義して変換した後、私たちはやっと私たちが望んでいるデータを得ることができます.
Stream
は、以下のような終了動作を提供する.Optional min(Comparator super T> comparator);
Optional max(Comparator super T> comparator);
long count();
boolean anyMatch(Predicate super T> predicate);
boolean allMatch(Predicate super T> predicate);
boolean noneMatch(Predicate super T> predicate);
void forEach(Consumer super T> action);
void forEachOrdered(Consumer super T> action);
Optional findFirst();
Optional findAny();
// reduce 。 (accumulator)op
// v1 op v2 op v3 ...
// identity,
Optional reduce(BinaryOperator accumulator);
T reduce(T identity, BinaryOperator accumulator);
U reduce(U identity,BiFunction accumulator,BinaryOperator combiner);
もちろん,変換後のストリームは必ずしも上述した終端操作を行う必要はなく,得られた結果を集合に格納して用いることもできる.
// iterator, iterator
Iterator iterator();
Object[] toArray();
A[] toArray(IntFunctiongenerator);
R collect(Collector super T, A, R> collector);
R collect(Supplier supplier,BiConsumer accumulator,BiConsumer combiner)
collect
の方法については、Stream.of(1,2,3,4).collect(Collectors.toSet())
のような異なるコレクタを定義することによって、Set
のような異なる集合タイプを得ることができる.コレクタCollectors
には、以下のような方法(部分)があり、方法の説明は注釈部分にある.public static Collector> toList();
public static Collector> toSet();
// keyMapper key, valueMapper value, mergeFunction key
// :Map idName=people.collect(Collectors.toMap(Person::getId,Person::getName,
// (existValue,newValue)->existValue))
public static Collector> toMap(Function super T, ? extends K> keyMapper
,Function super T, ? extends U> valueMapper);
public static Collector> toMap(Function super T, ? extends K> keyMapper
,Function super T, ? extends U> valueMapper,BinaryOperator mergeFunction)
//
// :person.collect(Collectors.toCollection(TreeSet::new))
public static >
Collector toCollection(Supplier collectionFactory);
// , 、
public static Collector joining();
public static Collector joining(CharSequence delimiter);
public static Collector joining(CharSequence delimiter,
CharSequence prefix,
CharSequence suffix);
// (Int|Long|Double)SummaryStatistics
/* (Int|Long|Double)SummaryStatistics
* getCount()
* getSum()
* getAverage()
* getMax()、getMin() / , (MAX|MIN)_VALUE
* :Stream.of(1,2,3,4).collect(Collectors.summaringzingInt(x->x)).getCount();
*/
public static
Collector summarizingInt(ToIntFunction super T> mapper);
public static
Collector summarizingLong(ToLongFunction super T> mapper);
public static
Collector summarizingDouble(ToDoubleFunction super T> mapper)
//
/*
* classifier , Persion::getName
* mapFactory , TreeMap::new
* downstream , counting()、summingInt()、maxBy(Cmparator)、minBy()
* mapping(mapper,downstream)
*/
// :people.collect(
// Collectors.groupingBy(
// Person::getName,
// Collectors.mapping(Person::getId,Collectors.counting())))
public static Collector>>
groupingBy(Function super T, ? extends K> classifier)
public static
Collector> groupingBy(Function super T, ? extends K> classifier,
Collector super T, A, D> downstream)
public static >
Collector groupingBy(Function super T, ? extends K> classifier,
Supplier mapFactory,Collector super T, A, D> downstream)
へいれつりゅう
パラレルストリームを作成して、ストリームの処理速度を速めることができます.ストリームを取得する方法には、
Strea.parallel()
を使用する方法と、Collection.parallelStreamm()
を使用してセットから並列ストリームを取得する方法の2つがあります.終了メソッドの実行時にストリームが並列状態にある限り、すべての中間操作が並列に実行されます.