4

次のように、ラムダ式の要素で行われることをチェーン/連結することができます。

list.forEach(s -> {
        System.out.println(s.toLowerCase());
        System.out.println(s.toUpperCase());
});

メソッド参照でもこれを行う方法はありますか? このようなもの:

list.forEach({
    System.out::println(String::toLowerCase);
    System.out::println(String::toCase);
});

私はこれを4つの別々の呼び出しで行うことができることを知っています(値を変更するというより多くのことも行います):

list.replaceAll(String::toLowerCase);
list.forEach(System.out::println);
list.replaceAll(String::toUpperCase);
list.forEach(System.out::println);

私はこのような簡単なことさえできません:

list.forEach({
    System.out::println;
    System.out::println;
});
4

3 に答える 3

3

いいえ、提案したようにメソッド参照を使用することはできません。メソッド参照は、実際にはラムダ式の構文上の置き換えにすぎません。そのため、代わりに:

text -> console.print(text)

不要な変数の導入を避け、代わりに使用できます

console::print

したがって、次のようなことはできないと言うと、次のようになります。

list.forEach({
    System.out::println;
    System.out::println;
});

これは単なる構文上のショートカットです

list.forEach({
    c -> System.out.println(c);
    c -> System.out.println(c);
});

これは本当に意味がありません。リスト内の項目を表す変数はなく (ブロックの外にある必要があります)、2 つの「ステートメント」は何も適用されないラムダ式です。

メソッド参照は、不要な変数を避けるための非常に巧妙なショートカットですが、より冗長なラムダ式の代わりにすぎず、ブロック内の独立したステートメントとして使用することはできません。

于 2015-07-25T11:26:13.807 に答える
3

There is no point in converting

list.forEach(s -> {
    System.out.println(s.toLowerCase());
    System.out.println(s.toUpperCase());
});

to

list.forEach({
    System.out::println(String::toLowerCase);
    System.out::println(String::toUpperCase);
});

as there is no win in clarity, the latter even consists of more characters than the former, if we use the same indention and insert the Upper you have left off the second variant. So why should we have such an alternative form?

Method reference have been invented as a feature allowing a dense syntax for a single method delegation, were declaring and referencing the parameters could really make a difference. Even replacing a sole s->System.out.println(s) with System.out::println is no that big win, but at least, there is some. Further, encoding the method reference at bytecode level can be more compact because the target method can be directly referenced just like the synthetic method holding a lambda expression’s code. For compound method references, there is no such compact form.


Since your desired operation consist of operations of different kinds, you may use the Stream API, which is intended to combine such operations:

list.stream().flatMap(s->Stream.of(s.toLowerCase(), s.toUpperCase()))
    .forEach(System.out::println);

and if you want to include method references for everything, at all costs, you may do it the following way:

list.stream()
    .flatMap(s->Stream.<UnaryOperator<String>>of(String::toLowerCase, String::toUpperCase)
        .map(f->f.apply(s)))
    .forEach(System.out::println);
于 2015-07-27T12:50:04.123 に答える