将逗号分隔的字符串转换为 HashSet

25

那么,您要如何进行转换呢?

String csv = "11,00,33,66,44,33,22,00,11";

以最快、最优化的方式将其转换为哈希集。

这适用于用户ID列表。

更新

我通过一个测试程序运行了所有提供的答案,其中每种方法针对更大的CSV字符串调用了500,000次。 连续进行了5次此测试(以防程序启动减慢了初始方法),我得到了以下结果(以毫秒为单位):

Method One Liner->  6597
Method Split&Iterate->  6090
Method Tokenizer->  4306
------------------------------------------------
Method One Liner->  6321
Method Split&Iterate->  6012
Method Tokenizer->  4227
------------------------------------------------
Method One Liner->  6375
Method Split&Iterate->  5986
Method Tokenizer->  4340
------------------------------------------------
Method One Liner->  6283
Method Split&Iterate->  5974
Method Tokenizer->  4302
------------------------------------------------
Method One Liner->  6343
Method Split&Iterate->  5920
Method Tokenizer->  4227
------------------------------------------------


static void method0_oneLiner() {
        for (int j = 0; j < TEST_TIMES; j++) {
            Set<String> hashSet = new HashSet<String>(Arrays.asList(csv
                    .split(",")));
        }
    }

    // ———————————————————————————————–

    static void method1_splitAndIterate() {

        for (int j = 0; j < TEST_TIMES; j++) {
            String[] values = csv.split(",");
            HashSet<String> hSet = new HashSet<String>(values.length);
            for (int i = 0; i < values.length; i++)
                hSet.add(values[i]);
        }
    }

    static void method2_tokenizer() {

        for (int j = 0; j < TEST_TIMES; j++) {
            HashSet<String> hSet = new HashSet<String>();
            StringTokenizer st = new StringTokenizer(csv, ",");
            while (st.hasMoreTokens())
                hSet.add(st.nextToken());
        }
    }

你有多少这些数字,或者你是如何确定这个特定的代码需要“最快最优化”的? - Kayaman
我正在编写一个分析算法,因为我正在使用一组巨大的数据集(noSQL数据库:(),所以我们将数据集分成较小的集合,然后将其转换为内存中的哈希集合以解决特定问题。我对此进行了分析,发现每次都需要花费几分钟的时间,因此我想要最快的可用选项,而不涉及使用C语言编写或转换nosql数据库中的数据。实际上,我无法访问这些数据。 - Menelaos
看看我提供的答案,稍微优化了一下。除非你可以从数据库中获取数据流并使用StreamTokenizer,否则很难超越它。 - Kayaman
10个回答

34
String[] values = csv.split(",");
Set<String> hashSet = new HashSet<String>(Arrays.asList(values));

15

其他6个答案很好,因为它们是最直接的转换方式。

然而,由于String.split()涉及正则表达式,而Arrays.asList正在进行冗余转换,你可能想以这种方式来做,这可能会在性能上有所改善。

编辑如果你大致知道你将要拥有多少项,请使用HashSet构造函数参数来避免不必要的调整大小/哈希:

HashSet<String> myHashSet = new HashSet(500000);  // Or a more realistic size
StringTokenizer st = new StringTokenizer(csv, ",");
while(st.hasMoreTokens())
   myHashSet.add(st.nextToken());

是的,这确实是连续最快的解决方案。即使csv元素不大于hashSet初始容量,这也是正确的。 - Menelaos
1
正如SagarG所指出的那样,StringTokenizer的使用已被弃用,因为它是一个遗留类。文档建议改用java.util.regex包代替 (http://docs.oracle.com/javase/7/docs/api/java/util/StringTokenizer.html)。 - Pietro Saccardi
4
我感谢您的回答,我不一定会在新代码中开始使用 StringTokenizer,但是使用正则表达式会很慢,这一点在问题和我的回答中都很清楚。我认为可以使用 Scanner 来避免遗留问题和速度问题。 - Kayaman

10
Arrays.stream(csv.split(",")).collect(Collectors.toSet());

5
您可以尝试一下。
Set<String> set= new HashSet<String>(Arrays.asList(yourString.split(",")));

3

试试这个:

Set<String> hashSet = new HashSet<>(Arrays.asList(csv.split(",")));

但要小心,这可能是最简单的方法,但不一定是最优解。


1
String[] array= csv.split(",");

Set<String> set = new HashSet<String>(Arrays.asList(array));

1

目前被@Kayaman接受的答案不错,但我想从Java API网页上补充一些内容。由于声誉不够,我无法将其作为评论添加到答案中。

不建议使用StringTokenizer。在Java API网页http://docs.oracle.com/javase/7/docs/api/java/util/StringTokenizer.html中提到了这一点。

StringTokenizer是一个遗留类,为了兼容性而保留,尽管在新代码中不鼓励使用它。建议任何寻求此功能的人使用String的split方法或java.util.regex包代替。

这应该是对已接受答案的编辑,因为它本身不是一个答案。 - Pietro Saccardi
兄弟Pietro。我一开始尝试将此内容作为评论添加到原始答案中,但系统显示我没有足够的声望来发表评论。然后我尝试编辑答案,但我的编辑被“Peer”拒绝,称这应该作为评论而不是编辑发布。最终,这是我发表想法的唯一方式。 - SagarG
为了知识而努力,这就是我的全部 :D 如果你想要,我可以将其作为评论发布,结束你的探索 :D - Pietro Saccardi
笑。请继续。 - SagarG
如果你熟悉你提到的 java.util.regex 包,我建议你在回答中加入使用它的解决方案,以使其对其他读者有用。 - Pietro Saccardi
@SagarG 我很感激你的回答,虽然我不会在新代码中使用StringTokenizer,但是使用正则表达式会很慢,这一点在问题和我的回答中都很明显。我猜测Scanner可能被用来避免旧版和缓慢的方面。 - Kayaman

0

try,

String[] splitValues = csv.split(",");
Set<String> set = new HashSet<String>(Arrays.asList(splitValues));

并且使用

CollectionUtils

collectionutils.addall();

0

尝试

String[] args = csv.split(",");
Set<String> set = new HashSet<String>(Arrays.asList(args));

0

在更新的Java版本中:

import java.util.Set;
Set<String> hashSet = Set.of(csv.split(","));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接