Java 将番石榴集转换为列表的最快方法

Java 将番石榴集转换为列表的最快方法,java,list,optimization,set,guava,Java,List,Optimization,Set,Guava,我甚至不确定这是否可行,但我正在执行一个集合操作,如联合或交叉,我需要将其转换为列表,以便对列表进行无序排列,并将其传递给另一个方法,该方法接受列表,而不是集合。因此,我将结果转换为列表,一切都很好。但是从分析器中,我看到这个操作在负载下花费了很长时间,这是因为Guava设置.size()的方式。它不像普通的java集合那样是一个常量操作 下面是代码示例 @测试 void testSet(){ Set first=ImmutableSet.of('a','b','c'); Set second=

我甚至不确定这是否可行,但我正在执行一个集合操作,如
联合
交叉
,我需要将其转换为
列表
,以便对列表进行无序排列,并将其传递给另一个方法,该方法接受
列表
,而不是
集合
。因此,我将结果转换为
列表
,一切都很好。但是从分析器中,我看到这个操作在负载下花费了很长时间,这是因为Guava设置
.size()
的方式。它不像普通的java集合那样是一个常量操作

下面是代码示例

@测试
void testSet(){
Set first=ImmutableSet.of('a','b','c');
Set second=ImmutableSet.of('b','c','d');
集合并集=集合并集(第一、第二);
列表字符=新数组列表(联合);
}
我正试图找到最快的方法将番石榴
集合
转换为
列表
。通过代码挖掘,这就是番石榴集所做的。这不是一个恒定的操作,在高负载下会影响性能。我猜,
.size
调用是从Java想要将新集合复制到新列表时开始的,它必须知道创建列表的大小。

将“高负载下的性能”参数放在一边(如果它与您的用例真的相关,我建议执行适当的JMH微基准),
集合
操作是内存优化的,因此,如果您要立即复制数据,您可能需要尝试完全不调用大小的不同方法

首先,
Sets.union
返回一个不可变的列表(可以将所有操作链接在一起):


也就是说,YMMV,我再次鼓励您在选择任何可读性较差的选项之前先做微基准测试。

“在加载过程中花费很长时间”-您怎么知道?你说的“很长时间”是什么意思?你说的“负载不足”是什么意思?这些都是非常模糊的指标,您可能无法正确解释分析器的输出。也就是说,我研究了
Set#union()
的实现,我能说的就是。。。哇,令人失望。同样相关的还有:
ImmutableSet.builder().addAll(第一个).addAll(第二个).build().asList()
为什么要通过
Multiset
而不是只构建
ImmutableSet.builder()
重复数据消除。哇,我设计得太过火了,谢谢Louis提出这个问题!我将编辑我的答案。
@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');
}
@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');
}