マップ機能が必要です。このようなJavaの何かはすでにありますか?
(不思議に思う人のために:もちろん私はこの些細な機能を自分で実装する方法を知っています...)
マップ機能が必要です。このようなJavaの何かはすでにありますか?
(不思議に思う人のために:もちろん私はこの些細な機能を自分で実装する方法を知っています...)
回答:
JDKには、Java 6以降の関数という概念はありません。
GuavaにはFunctionインターフェイスがありますが、この
メソッドは必要な機能を提供します。
Collections2.transform(Collection<E>, Function<E,E2>)
例:
// example, converts a collection of integers to their
// hexadecimal string representations
final Collection<Integer> input = Arrays.asList(10, 20, 30, 40, 50);
final Collection<String> output =
Collections2.transform(input, new Function<Integer, String>(){
@Override
public String apply(final Integer input){
return Integer.toHexString(input.intValue());
}
});
System.out.println(output);
出力:
[a, 14, 1e, 28, 32]
最近、Java 8には実際にマップ関数があるので、おそらくコードをより簡潔に記述します。
Collection<String> hex = input.stream()
.map(Integer::toHexString)
.collect(Collectors::toList);
Collections2.transform(input -> Integer.toHexString(intput.intValue())
Java 8以降、JDKでこれを行うための標準オプションがいくつかあります。
Collection<E> in = ...
Object[] mapped = in.stream().map(e -> doMap(e)).toArray();
// or
List<E> mapped = in.stream().map(e -> doMap(e)).collect(Collectors.toList());
java.util.Collection.stream()
およびを参照してくださいjava.util.stream.Collectors.toList()
。
toList()
ます。別のタイプへの置換:(List<R>)((List) list).replaceAll(o -> doMap((E) o));
e -> doMap(e)
ちょうどで置き換えることができますdoMap
か?
foo::doMap
またはのようなものFoo::doMap
。
Javaに必要な多くの機能を処理する、Functional Javaと呼ばれる素晴らしいライブラリがありますが、そうではありません。さらに、Javaがすべきことをすべて実行しますが、JVM用に作成されたものとの互換性はまだない、この素晴らしい言語Scalaもあります。
a.map({int i => i + 42});
コンパイラを拡張しましたか?または追加されたプリプロセッサ?
非常に注意してください Collections2.transform()
グアバから。その方法の最大の利点は、その最大の危険でもある遅延です。
ドキュメントを見てLists.transform()
、私はにも適用されると信じて、Collections2.transform()
:
関数は遅延して適用され、必要なときに呼び出されます。これは、返されるリストがビューになるために必要ですが、List.contains(java.lang.Object)やList.hashCode()などの一括操作に対して関数が何度も適用されることを意味します。これがうまく機能するには、機能が高速でなければなりません。返されるリストがビューである必要がないときに遅延評価を回避するには、返されるリストを選択した新しいリストにコピーします。
また、Collections2.transform()
それらのドキュメントでは、ライブビューを取得すると記載されていますが、ソースリストの変更は変換されたリストに影響します。この種の動作は、開発者が動作方法を理解していない場合、追跡が困難な問題を引き起こす可能性があります。
より古典的な「マップ」が必要な場合、それは1度だけ実行されます。さらにFluentIterable
、操作がはるかに簡単なGuavaのを使用したほうがよいでしょう。ここにそれのためのグーグルの例があります:
FluentIterable
.from(database.getClientList())
.filter(activeInLastMonth())
.transform(Functions.toStringFunction())
.limit(10)
.toList();
transform()
これがmapメソッドです。と同じFunction <>「コールバック」を使用しCollections.transform()
ます。返されるリストは読み取り専用ですが、copyInto()
読み書きリストを取得するために使用します。
それ以外の場合はもちろん、java8にラムダが付属している場合、これは廃止されます。
これは、マップを使用できる別の機能ライブラリです。http://code.google.com/p/totallylazy/
sequence(1, 2).map(toString); // lazily returns "1", "2"
古い質問ですが、別の解決策を示したいと思います。
Java GenericsとJava 8ストリームを使用して独自の操作を定義するだけです。
public static <S, T> List<T> map(Collection<S> collection, Function<S, T> mapFunction) {
return collection.stream().map(mapFunction).collect(Collectors.toList());
}
次のようなコードを書くことができます:
List<String> hex = map(Arrays.asList(10, 20, 30, 40, 50), Integer::toHexString);