Saya membutuhkan fungsi peta . Apakah sudah ada yang seperti ini di Jawa?
(Bagi mereka yang bertanya-tanya: Saya tentu saja tahu sendiri bagaimana mengimplementasikan fungsi sepele ini ...)
Saya membutuhkan fungsi peta . Apakah sudah ada yang seperti ini di Jawa?
(Bagi mereka yang bertanya-tanya: Saya tentu saja tahu sendiri bagaimana mengimplementasikan fungsi sepele ini ...)
Jawaban:
Tidak ada gagasan tentang fungsi di JDK pada java 6.
Jambu memiliki antarmuka fungsi dan
metode menyediakan fungsionalitas yang Anda butuhkan.
Collections2.transform(Collection<E>, Function<E,E2>)
Contoh:
// 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);
Keluaran:
[a, 14, 1e, 28, 32]
Saat ini, dengan Java 8, sebenarnya ada fungsi peta, jadi saya mungkin akan menulis kode dengan cara yang lebih ringkas:
Collection<String> hex = input.stream()
.map(Integer::toHexString)
.collect(Collectors::toList);
Collections2.transform(input -> Integer.toHexString(intput.intValue())
Sejak Java 8, ada beberapa opsi standar untuk melakukan ini di 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());
Lihat java.util.Collection.stream()
dan java.util.stream.Collectors.toList()
.
toList()
. Mengganti ke jenis yang berbeda:(List<R>)((List) list).replaceAll(o -> doMap((E) o));
e -> doMap(e)
diganti dengan adil doMap
?
foo::doMap
atau Foo::doMap
.
Ada perpustakaan indah yang disebut Java Fungsional yang menangani banyak hal yang Anda ingin memiliki Jawa tetapi tidak. Kemudian lagi, ada juga bahasa Scala yang luar biasa ini yang melakukan semua yang seharusnya dilakukan oleh Java tetapi tetap kompatibel dengan apa pun yang ditulis untuk JVM.
a.map({int i => i + 42});
apakah mereka memperpanjang compiler? atau menambahkan preprosesor?
Berhati-hatilah dengan Collections2.transform()
dari jambu biji. Keuntungan terbesar metode itu juga bahaya terbesarnya: kemalasannya.
Lihatlah dokumentasi Lists.transform()
, yang saya percaya berlaku juga untuk Collections2.transform()
:
Fungsi ini diterapkan dengan malas, dipanggil saat dibutuhkan. Ini diperlukan untuk daftar yang dikembalikan menjadi tampilan, tetapi itu berarti bahwa fungsi akan diterapkan berkali-kali untuk operasi massal seperti List.contains (java.lang.Object) dan List.hashCode (). Agar ini berfungsi dengan baik, fungsinya harus cepat. Untuk menghindari evaluasi malas ketika daftar yang dikembalikan tidak perlu dilihat, salin daftar yang dikembalikan ke daftar baru yang Anda pilih.
Juga dalam dokumentasi Collections2.transform()
mereka menyebutkan Anda mendapatkan tampilan langsung, bahwa perubahan dalam daftar sumber mempengaruhi daftar yang diubah. Perilaku semacam ini dapat menyebabkan masalah yang sulit dilacak jika pengembang tidak menyadari cara kerjanya.
Jika Anda menginginkan "peta" yang lebih klasik, yang akan berjalan sekali dan sekali saja, maka Anda lebih baik FluentIterable
, juga dari Guava, yang memiliki operasi yang jauh lebih sederhana. Ini adalah contoh google untuk itu:
FluentIterable
.from(database.getClientList())
.filter(activeInLastMonth())
.transform(Functions.toStringFunction())
.limit(10)
.toList();
transform()
di sini adalah metode peta. Ini menggunakan Fungsi yang sama <> "callbacks" seperti Collections.transform()
. Daftar yang Anda dapatkan hanya baca-saja, gunakan copyInto()
untuk mendapatkan daftar baca-tulis.
Kalau tidak tentu saja ketika java8 keluar dengan lambdas, ini akan usang.
Ini adalah fungsi fungsional lain yang dengannya Anda dapat menggunakan peta: http://code.google.com/p/totallylazy/
sequence(1, 2).map(toString); // lazily returns "1", "2"
Meskipun ini adalah pertanyaan lama, saya ingin menunjukkan solusi lain:
Cukup tentukan operasi Anda sendiri menggunakan java generics dan java 8 stream:
public static <S, T> List<T> map(Collection<S> collection, Function<S, T> mapFunction) {
return collection.stream().map(mapFunction).collect(Collectors.toList());
}
Daripada Anda dapat menulis kode seperti ini:
List<String> hex = map(Arrays.asList(10, 20, 30, 40, 50), Integer::toHexString);