2017年 2月

Java SE 9 の予習 その2

Java

Java SE 9 の予習 その2です。

Java SE 8 でインタフェースにデフォルトメソッドと静的メソッドが実装できるようになりました。

しかし、使い勝手はお世辞にも良いとは言えませんでした。

Java でプログラムを組む上で重要なのはインタフェースの設計にあるからです。

デフォルトメソッドが実装された理由は Java SE 8 でインタフェースにメソッドを追加すると実装クラスに与える影響が大きく既存のプログラムに破綻を生じるケースも考えられたからです。

そんな事情からインタフェースにデフォルトメソッドが追加され実装がインタフェースにされるようになりました。

Java SE 9 からはさらにプライベートメソッドが実装できるようになります。

これでデフォルトメソッドの実装内容の非公開にしたい所をインタフェース経由で公開してしまうようなことは無くなります。

とりあえずプログラムを組んで動作確認をしてみました。

 

このプログラムの実行結果は次のようになります。

I ate strawberry cake. It was very delicious.
I ate tiramisu cake.
I will eat another TiramisuCake.
I ate cheese cake.
I will eat another cheese cake.
I ate chocolate cake.

Java SE 9 ではこのような小さな改良がたくさんあるようです。(^_^)

Java SE 9 の予習

Hatena タグ:

Java SE 9 の予習

Java

今日は私の○X回目の誕生日です。

今年は忘れられずにお祝いのプレゼントまでいただきました。(^_^)

いくつになっても誕生日を祝ってもらえるのは嬉しいものです。

と言うわけでお誕生日記念として今年の夏にリリース予定の Java SE 9 の予習をはじめます。

Java SE 9 と言えば Project Jigsaw, Project Kulla (JShell) が目玉となっています。

これらはこれから日本語での情報もたくさん出てくると思うので後回しとします。(既に最新Java情報局で記事があります。)

故に Java SE 9 を使うのであれば必要最低限これだけは覚えておきたいことを自分用メモとして載せておきます。

完全に自分用のメモです!

static <E> List<E> of()

Returns an immutable list containing zero elements. See Immutable List Static Factory Methods for details.

Type Parameters:
E – the List’s element type

Returns:
an empty List
 

public Stream<T> stream()

If a value is present, returns a sequential Stream containing only that value, otherwise returns an empty Stream.

API Note:
This method can be used to transform a Stream of optional elements to a Stream of present value elements:
 
     Stream<Optional<T>> os = ..
     Stream<T> s = os.flatMap(Optional::stream)
 
Returns:
the optional value as a Stream

 

static <T> Stream<T> ofNullable(T t)

Returns a sequential Stream containing a single element, if non-null, otherwise returns an empty Stream.

Type Parameters:
T – the type of stream elements

Parameters:
t – the single element

Returns:
a stream with a single element if the specified element is non-null, otherwise an empty stream

 

public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction)

If a value is present, performs the given action with the value, otherwise performs the given empty-based action.

Parameters:
action – the action to be performed, if a value is presentemptyAction – the empty-based action to be performed, if no value is present

Throws:
NullPointerException – if a value is present and the given action is null, or no value is present and the given empty-based action is null.

 

public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier)

If a value is present, returns an Optional describing the value, otherwise returns an Optional produced by the supplying function.

Parameters:
supplier – the supplying function that produces an Optional to be returned

Returns:
returns an Optional describing the value of this Optional, if a value is present, otherwise an Optional produced by the supplying function.

Throws:
NullPointerException – if the supplying function is null or produces a null result

 

public static <T,A,R> Collector<T,?,R> filtering(Predicate<? super T> predicate, Collector<? super T,A,R> downstream)

Adapts a Collector to one accepting elements of the same type T by applying the predicate to each input element and only accumulating if the predicate returns true.

API Note:
The filtering() collectors are most useful when used in a multi-level reduction, such as downstream of a groupingBy or partitioningBy. For example, given a stream of Employee, to accumulate the employees in each department that have a salary above a certain threshold:
 
Map<Department, Set<Employee>> wellPaidEmployeesByDepartment
   = employees.stream().collect(
     groupingBy(Employee::getDepartment,
                filtering(e -> e.getSalary() > 2000,
                          toSet())));
 
A filtering collector differs from a stream’s filter() operation. In this example, suppose there are no employees whose salary is above the threshold in some department. Using a filtering collector as shown above would result in a mapping from that department to an empty Set. If a stream filter() operation were done instead, there would be no mapping for that department at all.

Type Parameters:
T – the type of the input elements
A – intermediate accumulation type of the downstream collector
R – result type of collector

Parameters:
predicate – a predicate to be applied to the input elements
downstream – a collector which will accept values that match the predicate

Returns:
a collector which applies the predicate to the input elements and provides matching elements to the downstream collector

 

public static <T,U,A,R> Collector<T,?,R> flatMapping(Function<? super T,? extends Stream<? extends U>> mapper, Collector<? super U,A,R> downstream)

Adapts a Collector accepting elements of type U to one accepting elements of type T by applying a flat mapping function to each input element before accumulation. The flat mapping function maps an input element to a stream covering zero or more output elements that are then accumulated downstream. Each mapped stream is closed after its contents have been placed downstream. (If a mapped stream is null an empty stream is used, instead.)

API Note:
The flatMapping() collectors are most useful when used in a multi-level reduction, such as downstream of a groupingBy or partitioningBy. For example, given a stream of Order, to accumulate the set of line items for each customer:
 
Map<String, Set<LineItem>> itemsByCustomerName
   = orders.stream().collect(
     groupingBy(Order::getCustomerName,
                flatMapping(order -> order.getLineItems().stream(),
                            toSet())));
 
Type Parameters:
T – the type of the input elements
U – type of elements accepted by downstream collector
A – intermediate accumulation type of the downstream collector
R – result type of collector

Parameters:
mapper – a function to be applied to the input elements, which returns a stream of results
downstream – a collector which will receive the elements of the stream returned by mapper

Returns:
a collector which applies the mapping function to the input elements and provides the flat mapped results to the downstream collector

 

default Stream<T> takeWhile(Predicate<? super T> predicate)

Returns, if this stream is ordered, a stream consisting of the longest prefix of elements taken from this stream that match the given predicate. Otherwise returns, if this stream is unordered, a stream consisting of a subset of elements taken from this stream that match the given predicate.
 
If this stream is ordered then the longest prefix is a contiguous sequence of elements of this stream that match the given predicate. The first element of the sequence is the first element of this stream, and the element immediately following the last element of the sequence does not match the given predicate.

If this stream is unordered, and some (but not all) elements of this stream match the given predicate, then the behavior of this operation is nondeterministic; it is free to take any subset of matching elements (which includes the empty set).

Independent of whether this stream is ordered or unordered if all elements of this stream match the given predicate then this operation takes all elements (the result is the same as the input), or if no elements of the stream match the given predicate then no elements are taken (the result is an empty stream).

This is a short-circuiting stateful intermediate operation.

API Note:
While takeWhile() is generally a cheap operation on sequential stream pipelines, it can be quite expensive on ordered parallel pipelines, since the operation is constrained to return not just any valid prefix, but the longest prefix of elements in the encounter order. Using an unordered stream source (such as generate(Supplier)) or removing the ordering constraint with BaseStream.unordered() may result in significant speedups of takeWhile() in parallel pipelines, if the semantics of your situation permit. If consistency with encounter order is required, and you are experiencing poor performance or memory utilization with takeWhile() in parallel pipelines, switching to sequential execution with BaseStream.sequential() may improve performance.

Implementation Requirements:
The default implementation obtains the spliterator of this stream, wraps that spliterator so as to support the semantics of this operation on traversal, and returns a new stream associated with the wrapped spliterator. The returned stream preserves the execution characteristics of this stream (namely parallel or sequential execution as per BaseStream.isParallel()) but the wrapped spliterator may choose to not support splitting. When the returned stream is closed, the close handlers for both the returned and this stream are invoked.

Parameters:
predicate – a non-interfering, stateless predicate to apply to elements to determine the longest prefix of elements.

Returns:
the new stream

 

default Stream<T> dropWhile(Predicate<? super T> predicate)

Returns, if this stream is ordered, a stream consisting of the remaining elements of this stream after dropping the longest prefix of elements that match the given predicate. Otherwise returns, if this stream is unordered, a stream consisting of the remaining elements of this stream after dropping a subset of elements that match the given predicate.
 
If this stream is ordered then the longest prefix is a contiguous sequence of elements of this stream that match the given predicate. The first element of the sequence is the first element of this stream, and the element immediately following the last element of the sequence does not match the given predicate.

If this stream is unordered, and some (but not all) elements of this stream match the given predicate, then the behavior of this operation is nondeterministic; it is free to drop any subset of matching elements (which includes the empty set).

Independent of whether this stream is ordered or unordered if all elements of this stream match the given predicate then this operation drops all elements (the result is an empty stream), or if no elements of the stream match the given predicate then no elements are dropped (the result is the same as the input).

This is a stateful intermediate operation.

API Note:
While dropWhile() is generally a cheap operation on sequential stream pipelines, it can be quite expensive on ordered parallel pipelines, since the operation is constrained to return not just any valid prefix, but the longest prefix of elements in the encounter order. Using an unordered stream source (such as generate(Supplier)) or removing the ordering constraint with BaseStream.unordered() may result in significant speedups of dropWhile() in parallel pipelines, if the semantics of your situation permit. If consistency with encounter order is required, and you are experiencing poor performance or memory utilization with dropWhile() in parallel pipelines, switching to sequential execution with BaseStream.sequential() may improve performance.

Implementation Requirements:
The default implementation obtains the spliterator of this stream, wraps that spliterator so as to support the semantics of this operation on traversal, and returns a new stream associated with the wrapped spliterator. The returned stream preserves the execution characteristics of this stream (namely parallel or sequential execution as per BaseStream.isParallel()) but the wrapped spliterator may choose to not support splitting. When the returned stream is closed, the close handlers for both the returned and this stream are invoked.

Parameters:
predicate – a non-interfering, stateless predicate to apply to elements to determine the longest prefix of elements.

Returns:
the new stream

 

static IntStream iterate(int seed, IntPredicate hasNext, IntUnaryOperator next)

Returns a sequential ordered IntStream produced by iterative application of the given next function to an initial element, conditioned on satisfying the given hasNext predicate. The stream terminates as soon as the hasNext predicate returns false.
 
IntStream.iterate should produce the same sequence of elements as produced by the corresponding for-loop:

     for (int index=seed; hasNext.test(index); index = next.applyAsInt(index)) {
         …
     }
 

The resulting sequence may be empty if the hasNext predicate does not hold on the seed value. Otherwise the first element will be the supplied seed value, the next element (if present) will be the result of applying the next function to the seed value, and so on iteratively until the hasNext predicate indicates that the stream should terminate.

The action of applying the hasNext predicate to an element happens-before the action of applying the next function to that element. The action of applying the next function for one element happens-before the action of applying the hasNext predicate for subsequent elements. For any given element an action may be performed in whatever thread the library chooses.

Parameters:
seed – the initial element
hasNext – a predicate to apply to elements to determine when the stream must terminate.
next – a function to be applied to the previous element to produce a new element

Returns:
a new sequential IntStream

 

static <T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)

Returns a sequential ordered Stream produced by iterative application of the given next function to an initial element, conditioned on satisfying the given hasNext predicate. The stream terminates as soon as the hasNext predicate returns false.
 
Stream.iterate should produce the same sequence of elements as produced by the corresponding for-loop:

     for (T index=seed; hasNext.test(index); index = next.apply(index)) {
         …
     }
 

The resulting sequence may be empty if the hasNext predicate does not hold on the seed value. Otherwise the first element will be the supplied seed value, the next element (if present) will be the result of applying the next function to the seed value, and so on iteratively until the hasNext predicate indicates that the stream should terminate.

The action of applying the hasNext predicate to an element happens-before the action of applying the next function to that element. The action of applying the next function for one element happens-before the action of applying the hasNext predicate for subsequent elements. For any given element an action may be performed in whatever thread the library chooses.

Type Parameters:
T – the type of stream elements

Parameters:
seed – the initial element
hasNext – a predicate to apply to elements to determine when the stream must terminate.
next – a function to be applied to the previous element to produce a new element

Returns:
a new sequential Stream

 

API ドキュメントが英語しかないのが残念(>_<)

正式リリースされる頃には日本語版が出ることを祈ろう!

Java SE 8 からの痒いところに手が届いたようなアップデートだけどかなり便利になる。

なぜ初めからこうしなかったんだろうと思うほどに。

でも zip, pair はまだ無いまま・・・

Java SE 10 まで待つことになるのか必要ないと判断されたのか?

他にもいろいろ細かいところが良くなっているようだから正式リリースが楽しみですね!

Hatena タグ: