java - 将 Guava Sets 转换为 List 的最快方法
问题描述
我什至不确定这是否可行,但我正在执行类似union
or的 Set 操作intersection
,我需要将其转换为 aList
以便对列表进行洗牌并将其传递给接受 aList
而不是a 的不同方法Set
。所以我将结果转换为 a List
,一切都很好。但是从分析器中,我看到该操作在负载下需要很长时间,这是因为 Guava Sets 的方式.size()
。它不是像普通 java Set 那样的常量操作。
这是代码示例
@Test
void testSet() {
Set<Character> first = ImmutableSet.of('a', 'b', 'c');
Set<Character> second = ImmutableSet.of('b', 'c', 'd');
Set<Character> union = Sets.union(first, second);
List<Character> characters = new ArrayList<>(union);
}
我正在尝试找到将 Guava 转换Sets
为List
. 通过挖掘代码,这就是 Guava Sets 所做的事情https://github.com/google/guava/blob/master/guava/src/com/google/common/collect/Sets.java#L694。这不是一个持续的操作,它会损害高负载下的性能。我猜这个.size
调用是从 Java 想要将一个新的 Collection 复制到一个新的 List 时开始的,它必须知道创建一个 List 的大小。
解决方案
抛开“高负载下的性能”的论点(如果它与您的用例真正相关,我建议做适当的 JMH 微基准测试),Sets
操作是内存优化的,所以如果您要立即复制数据,您可能想尝试不同的方法根本不叫大小。
首先,Sets.union
返回SetView<E>
which has immutableCopy()
,然后您可以在其上调用.asList()
view,返回一个不可变列表(随意将所有操作链接在一起):
@Test
public void testSetCopy() {
Set<Character> first = ImmutableSet.of('a', 'b', 'c');
Set<Character> second = ImmutableSet.of('b', 'c', 'd');
Sets.SetView<Character> union = Sets.union(first, second);
List<Character> characters = union.immutableCopy().asList();
assertThat(characters).containsOnly('a', 'b', 'c', 'd');
}
其次,您也可以Set
首先考虑使用,如 Louis 所说:
@Test
public void testMultiset() {
Set<Character> first = ImmutableSet.of('a', 'b', 'c');
Set<Character> second = ImmutableSet.of('b', 'c', 'd');
// here it's ugly but maybe you can collect to set in the first place
ImmutableMultiset<Character> set = ImmutableSet.<Character>builder()
.addAll(first)
.addAll(second)
.build(); // [a, b, c, d]
List<Character> characters = set.asList();
assertThat(characters).containsOnly('a', 'b', 'c', 'd');
}
也就是说,YMMV,我再次鼓励您在选择任何可读性较差的选项之前进行微基准测试。
推荐阅读
- python - Pandas 使用字典追加行以某种方式为某些新字典项添加列
- c++ - vscode c++调试器包含路径配置
- swift - 使用大导航标题时如何使视图居中?
- amazon-web-services - Lambda Resource-Based Policy 中 principal 和 source-account 的区别
- swift - 使用未解析的标识符 'FUIEmailAuth'FUIEmailAuth
- javascript - firebase 云计划功能不在控制台上打印任何内容
- android - Android config firebase realtime database rule for normal user access
- php - 带有 HTML/PHP putput 的 PHP 条件
- macos - 在 MacBook Pro 上使用 pytorch Cuda
- java - 如何使用 Bukkit/Spigot API 重新创建抓钩摆动效果?