gpt4 book ai didi

Java:如何将集合划分为等价类?

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:40:43 24 4
gpt4 key购买 nike

我有一个项目列表(!):

  • 一个
  • B
  • C
  • D
  • E
  • ...

我想将它们分组:

  • [A、C、D]
  • [B, E]
  • ...

组定义为:

  • 根据自定义函数f(a, b) -> boolean
  • ,组中的所有项目都相等
  • f(a, b) = f(b, a)

问题:是否有现成的 API 可以这样做?

<T> List<List<T>> group(Collection<T> collection, BiFunction<T, T, Boolean> eqF);

更新。这个问题完全不适用于您可以定义一些质量作为分组依据的场景!在这种情况下,Java 8 Collectors.groupingBy 是最简单的答案。

我正在处理多维 vector ,相等函数如下所示:

  • 指标(a,b)<阈值

对于这种情况,定义哈希等于解决初始任务:)

最佳答案

您的场景听起来像是 groupingBy 收集器的一个很好的用例。通常,您不提供相等函数,而是提供提取限定符 的函数。然后将元素映射到列表中的这些限定符。

Map<Qualifier, List<T>> map = list.stream()
.collect(Collectors.groupingBy(T::getQualifier));

Collection<List<T>> result = map.values();

如果 T 的身份是您的限定符,您可以使用 Function.identity() 作为参数。

但是当您的限定符超过 T 的 1 个字段时,这就会成为一个问题。您可以使用元组类型来为 T 创建备用标识,但这只是到目前为止,因为每个字段数量都需要一个单独的元组类。


如果你想使用 groupingBy 你真的需要为 T 创建一个适度的替代标识,所以你不必更改 TequalshashCode 方法。

要创建正确的标识,您需要实现 equalshashCode(或者始终返回 0 以获得哈希码,但会降低性能).据我所知,没有用于此的 API 类,但我做了一个简单的实现:

interface AlternateIdentity<T> {    
public static <T> Function<T, AlternateIdentity<T>> mapper(
BiPredicate<? super T, Object> equality, ToIntFunction<? super T> hasher) {
return t -> new AlternateIdentity<T>() {
@Override
public boolean equals(Object other) {
return equality.test(t, other);
}

@Override
public int hashCode() {
return hasher.applyAsInt(t);
}
};
}
}

你可以这样使用:

Collection<List<T>> result
= list.stream()
.collect(Collectors.groupingBy(
AlternateIdentity.mapper(eqF, hashF)
))
.values();

其中 eqF 是您的函数,而 hashF 是哈希码函数,它对与 eqF 测试相同的字段进行哈希处理。 (同样,您也可以在 hashF 中返回 0,但正确的实现会加快速度。)

关于Java:如何将集合划分为等价类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39320582/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com