将番石榴集转换为列表的最快方法
Fastest way to convert Guava Sets to List
我什至不确定这是否可行,但我正在执行 union
或 intersection
之类的 Set 操作,我需要将其转换为 List
以便打乱列表并将其传递给接受 List
而不是 Set
的不同方法。所以我将结果转换为 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 想要将新集合复制到新列表时开始的,它必须知道创建列表的大小。
将“高负载下的性能”参数放在一边(如果它确实与您的用例相关,我建议进行适当的 JMH 微基准测试),Sets
操作是内存优化的,所以如果您要复制数据马上,您可能想尝试完全不调用大小的不同方法。
首先,Sets.union
returns SetView<E>
which has immutableCopy()
,然后你可以调用 .asList()
视图,返回一个不可变列表(随意将所有操作链接在一起):
@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,我再次鼓励您在选择任何可读性较差的选项之前进行微基准测试。
我什至不确定这是否可行,但我正在执行 union
或 intersection
之类的 Set 操作,我需要将其转换为 List
以便打乱列表并将其传递给接受 List
而不是 Set
的不同方法。所以我将结果转换为 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 想要将新集合复制到新列表时开始的,它必须知道创建列表的大小。
将“高负载下的性能”参数放在一边(如果它确实与您的用例相关,我建议进行适当的 JMH 微基准测试),Sets
操作是内存优化的,所以如果您要复制数据马上,您可能想尝试完全不调用大小的不同方法。
首先,Sets.union
returns SetView<E>
which has immutableCopy()
,然后你可以调用 .asList()
视图,返回一个不可变列表(随意将所有操作链接在一起):
@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,我再次鼓励您在选择任何可读性较差的选项之前进行微基准测试。