有効なルックアップを可能にする関連するハッシュ関数を持たないBiPredicate
があれば、線形プロービングのみを使用できます。もちろん、あなたが持っているより多くの結果のグループは、より悪いパフォーマンスになります、そこにそれをやって何の組み込みコレクターはありませんが、元groupingBy
コレクタに近い作業カスタムコレクタは
public static <T> Collector<T,?,Map<T,Set<T>>> groupingBy(BiPredicate<T,T> p) {
return Collector.of(HashMap::new,
(map,t) -> {
for(Map.Entry<T,Set<T>> e: map.entrySet())
if(p.test(t, e.getKey())) {
e.getValue().add(t);
return;
}
map.computeIfAbsent(t, x->new HashSet<>()).add(t);
}, (m1,m2) -> {
if(m1.isEmpty()) return m2;
m2.forEach((t,set) -> {
for(Map.Entry<T,Set<T>> e: m1.entrySet())
if(p.test(t, e.getKey())) {
e.getValue().addAll(set);
return;
}
m1.put(t, set);
});
return m1;
}
);
のように実装することができますが。あなたの特定のタスクのために
、それは
public static ByteBuffer readUnchecked(Path p) {
try {
return ByteBuffer.wrap(Files.readAllBytes(p));
} catch(IOException ex) {
throw new UncheckedIOException(ex);
}
}
と
Set<Set<Path>> groupsByContents = your stream of Path instances
.collect(Collectors.collectingAndThen(
Collectors.groupingBy(YourClass::readUnchecked, Collectors.toSet()),
map -> new HashSet<>(map.values())));
内容によってその意思グループファイルと暗黙的にハッシングんを使用することがはるかに効率的になります。等しいハッシュは等しい内容を意味するわけではないが、この解決策はすでにこれを処理していることに注意してください。仕上げ機能map -> new HashSet<>(map.values())
は、結果のコレクションが操作後にファイルの内容をメモリに保持しないようにします。
の可能性のある重複(https://stackoverflow.com/questions/36678571/how-to-partition-a -list-by-predicate-using-java8) – Oleg
あなたは投稿を読むのに気をつけますか?これは重複することはできませんが、私は明らかに、2つの要素をとりブール値を返す関数でパーティション化が可能かどうかを尋ねています。 –
なぜ人々はこれをdownvotingですか? –