Saya sedang bermain-main dengan Java 8 lambdas untuk dengan mudah menyaring koleksi. Tetapi saya tidak menemukan cara ringkas untuk mengambil hasilnya sebagai daftar baru dalam pernyataan yang sama. Inilah pendekatan saya yang paling ringkas sejauh ini:
List<Long> sourceLongList = Arrays.asList(1L, 10L, 50L, 80L, 100L, 120L, 133L, 333L);
List<Long> targetLongList = new ArrayList<>();
sourceLongList.stream().filter(l -> l > 100).forEach(targetLongList::add);
Contoh di internet tidak menjawab pertanyaan saya karena berhenti tanpa menghasilkan daftar hasil baru. Pasti ada cara yang lebih ringkas. Saya akan diharapkan, bahwa Stream
kelas memiliki metode seperti toList()
, toSet()
...
Apakah ada cara agar variabel targetLongList
dapat langsung ditugaskan oleh baris ketiga?
collections
lambda
java-8
java-stream
Daniel K.
sumber
sumber
sourceLongList
setelah itu adaCollection.removeIf(…)
untuk kenyamanan.List<Long> targetLongList = sourceLongList.stream().collect(Collectors.toList());
Jawaban:
Apa yang Anda lakukan mungkin merupakan cara paling sederhana, asalkan aliran Anda tetap berurutan — jika tidak, Anda harus melakukan panggilan ke sekuensial () sebelumnya
forEach
.[sunting kemudian: alasan pemanggilan sekuensial () diperlukan adalah karena kode yang ada (
forEach(targetLongList::add)
) akan bersemangat jika alirannya paralel. Bahkan kemudian, itu tidak akan mencapai efek yang dimaksudkan, sepertiforEach
yang secara eksplisit tidak ditentukan - bahkan dalam aliran berurutan urutan pemrosesan elemen tidak dijamin. Anda harus menggunakanforEachOrdered
untuk memastikan pemesanan yang benar. Maksud dari perancang Stream API adalah Anda akan menggunakan kolektor dalam situasi ini, seperti di bawah ini.]Alternatifnya adalah
sumber
toList
. Hal ini dilakukan dengan menempatkan berikut di antara impor file:static import java.util.stream.Collectors.toList;
. Kemudian panggilan kumpulkan hanya berbunyi.collect(toList())
.Collectors
kelas di Preferensi -> Java -> Editor -> Content Assist -> Favorites . Setelah ini, Anda hanya perlu mengetiktoLi
di tekan Ctr + Space untuk mengisi IDEtoList
dan menambahkan impor statis.IntStream
dan beberapa lainnya hampir-tetapi-tidak-Stream
cukup tidak memilikicollect(Collector)
metode dan Anda harus meneleponIntStream.boxed()
untuk mengubahnya menjadi biasaStream
terlebih dahulu. Kemudian lagi, mungkin Anda hanya ingintoArray()
.sequential()
sebelumforEach
atau menggunakan 'forEachOrdered`Diperbarui:
Pendekatan lain adalah menggunakan
Collectors.toList
:Solusi Sebelumnya:
Pendekatan lain adalah menggunakan
Collectors.toCollection
:sumber
Collectors::toList
javadoc: "Tidak ada jaminan pada jenis, mutabilitas, serializability, atau keamanan thread dari Daftar yang dikembalikan; jika diperlukan kontrol lebih besar terhadap Daftar yang dikembalikan, gunakantoCollection(Supplier)
."Saya suka menggunakan metode util yang mengembalikan kolektor untuk
ArrayList
ketika itulah yang saya inginkan.Saya pikir solusinya menggunakan
Collectors.toCollection(ArrayList::new)
agak terlalu berisik untuk operasi yang umum.Contoh:
Dengan jawaban ini saya juga ingin menunjukkan betapa sederhananya membuat dan menggunakan kolektor khusus, yang umumnya sangat berguna.
sumber
toList
jika Anda misalnya ingin mengubah daftar nanti di program. ThetoList
dokumentasi mengatakan ini: "Tidak ada jaminan pada jenis, berubah-ubah, serializability, atau benang-keselamatan Daftar kembali, jika lebih kontrol atas Daftar kembali diperlukan, penggunaantoCollection
." . Jawaban saya menunjukkan cara untuk membuatnya lebih mudah untuk melakukan itu dalam kasus umum.Jika Anda memiliki larik primitif, Anda dapat menggunakan koleksi primitif yang tersedia di Eclipse Collections .
Jika Anda tidak dapat mengubah sourceLongList dari
List
:Jika Anda ingin menggunakan
LongStream
:Catatan: Saya adalah kontributor untuk Eclipse Collections.
sumber
Cara yang sedikit lebih efisien (hindari pembuatan Daftar sumber dan buka otomatis oleh filter):
sumber
Ini adalah panggilan yang dapat Anda gunakan untuk mengonversi Streaming apa pun ke Daftar.
lebih konkret:
dari:
https://www.geeksforgeeks.org/collectors-tolist-method-in-java-with-examples/
sumber
Jika Anda tidak keberatan menggunakan perpustakaan pihak ketiga, cyclop-react lib (pengungkapan Saya adalah kontributor) AOL memiliki ekstensi untuk semua jenis Koleksi JDK , termasuk Daftar . Antarmuka ListX memperluas java.util.List dan menambahkan sejumlah besar operator yang berguna, termasuk filter.
Anda cukup menulis-
ListX juga dapat dibuat dari Daftar yang ada (via ListX.fromIterable)
sumber
Ada varian lain dari metode kumpulkan yang disediakan oleh kelas LongStream dan juga oleh kelas IntStream dan DoubleStream.
Melakukan operasi pengurangan yang bisa berubah pada elemen aliran ini. Pengurangan yang bisa berubah adalah di mana nilai yang dikurangi adalah wadah hasil yang bisa berubah, seperti ArrayList, dan elemen digabungkan dengan memperbarui status hasil alih-alih dengan mengganti hasilnya. Ini menghasilkan hasil yang setara dengan:
Seperti mengurangi (panjang, LongBinaryOperator), operasi pengumpulan dapat diparalelkan tanpa memerlukan sinkronisasi tambahan. Ini adalah operasi terminal.
Dan jawaban untuk pertanyaan Anda dengan metode kumpulkan ini adalah sebagai berikut:
Di bawah ini adalah varian referensi metode yang cukup pintar tetapi beberapa yang sulit dipahami:
Di bawah ini akan menjadi varian HashSet:
Varian LinkedList serupa adalah seperti ini:
sumber
Dalam kasus seseorang (seperti saya) di luar sana sedang mencari cara berurusan dengan Objek, bukan tipe primitif kemudian gunakan
mapToObj()
cetakan:
sumber
sumber
Berikut ini kode dari AbacusUtil
Pengungkapan : Saya pengembang AbacusUtil.
sumber
com.landawn.abacus.util.stream.LongStream
atauLongStreamEx
di AbacusUtilAnda dapat menulis ulang kode seperti di bawah ini:
sumber
Untuk mengumpulkan dalam daftar yang dapat diubah:
Untuk mengumpulkan dalam daftar yang tidak berubah:
Penjelasan
collect
dari javadoc :sumber
Jika Anda tidak menggunakan
parallel()
ini akan berhasilsumber
collect
dan kemudian tidak menyimpan nilai kembali. Dalam hal ini Anda dapat menggunakannyaforEach
sebagai gantinya. Tapi itu masih solusi yang buruk.