Saya memiliki peta Map<K, V>
dan tujuan saya adalah untuk menghapus nilai duplikat dan menampilkan struktur yang sama Map<K, V>
lagi. Dalam hal nilai duplikat ditemukan, harus ada satu kunci yang dipilih ( k
) dari dua kunci ( k1
dan k1
) yang memegang nilai-nilai ini, karena alasan ini, asumsikan BinaryOperator<K>
pemberian k
dari k1
dan k2
tersedia.
Contoh input dan output:
// Input
Map<Integer, String> map = new HashMap<>();
map.put(1, "apple");
map.put(5, "apple");
map.put(4, "orange");
map.put(3, "apple");
map.put(2, "orange");
// Output: {5=apple, 4=orange} // the key is the largest possible
Usaha saya menggunakan Stream::collect(Supplier, BiConsumer, BiConsumer)
adalah sedikit sangat kikuk dan berisi operasi bisa berubah seperti Map::put
dan Map::remove
yang saya ingin menghindari:
// // the key is the largest integer possible (following the example above)
final BinaryOperator<K> reducingKeysBinaryOperator = (k1, k2) -> k1 > k2 ? k1 : k2;
Map<K, V> distinctValuesMap = map.entrySet().stream().collect(
HashMap::new, // A new map to return (supplier)
(map, entry) -> { // Accumulator
final K key = entry.getKey();
final V value = entry.getValue();
final Entry<K, V> editedEntry = Optional.of(map) // New edited Value
.filter(HashMap::isEmpty)
.map(m -> new SimpleEntry<>(key, value)) // If a first entry, use it
.orElseGet(() -> map.entrySet() // otherwise check for a duplicate
.stream()
.filter(e -> value.equals(e.getValue()))
.findFirst()
.map(e -> new SimpleEntry<>( // .. if found, replace
reducingKeysBinaryOperator.apply(e.getKey(), key),
map.remove(e.getKey())))
.orElse(new SimpleEntry<>(key, value))); // .. or else leave
map.put(editedEntry.getKey(), editedEntry.getValue()); // put it to the map
},
(m1, m2) -> {} // Combiner
);
Apakah ada solusi menggunakan kombinasi yang tepat Collectors
dalam satu Stream::collect
panggilan (mis. Tanpa operasi yang bisa berubah)?
java
dictionary
java-8
java-stream
collectors
Nikolas
sumber
sumber
Stream
s?Map::put
atauMap::remove
di dalamCollector
.BiMap
. Kemungkinan merupakan duplikat Hapus nilai duplikat dari HashMap di JavaJawaban:
Anda dapat menggunakan Collectors.toMap
sumber
Coba ini: Cara sederhana adalah membalikkan kunci dan nilai kemudian gunakan
toMap()
kolektor dengan fungsi gabungan.sumber
map
dibeli operasi perantara . Anda tampaknya menukar kunci dan nilai, itu jelas, tapi apa gunanya, Anda bisa melakukan itu pada langkah kumpulkan sama saja?swap(); collect(key, value, binOp);
alih-alihcollect(value, key, binOp)
. Mungkin saya perlu mencoba ini secara singkat?Saya menemukan solusi non-stream lebih ekspresif:
Ini digunakan
Map.merge
dengan mengurangi dua fungsi dan digunakanLinkedHashMap
untuk mempertahankan urutan entri asli.sumber
Saya menemukan cara menggunakan hanya
Collectors
tanpa perlu mengumpulkan dan memproses lebih lanjut Peta yang dikembalikan lagi. Idenya adalah:Kelompokkan
Map<K, V>
keMap<V, List<K>
.Kurangi kunci baru (
List<K>
) untukK
menggunakanBinaryOperator<K>
.Balikkan
Map<V, K>
kembali keMap<K, V>
struktur lagi - yang aman karena kedua kunci dan nilai dijamin berbeda.Kode terakhir:
sumber
Pendekatan lain untuk mendapatkan hasil yang diinginkan dengan "Stream and Collectors.groupingBy".
sumber