【问题标题】:Convert comma separated string into a HashSet将逗号分隔的字符串转换为 HashSet
【发布时间】:2013-09-30 22:26:28
【问题描述】:

那么,你将如何转换

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

以最快最优化的方式到一个哈希集。

这是一个用户ID列表。

更新

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

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());
        }
    }

【问题讨论】:

  • 你有多少这样的数字,或者你如何确定这个特定的代码需要“最快最优化”?
  • 我正在编写一个分析算法,因为我正在使用一个巨大的数据集(noSQL DB :( ),我们将数据集分成更小的集合,然后转换为内存中的哈希集对于一个特定的问题。我对此进行了分析,它每次都会消耗几分钟,所以我希望有最快的可用选项,不涉及用 C 编写它,或者在 nosql db 中转换数据。我实际上不无法访问数据。
  • 查看我提供的答案以获得稍微优化的版本。很难做到这一点,除非可能使用 StreamTokenizer(如果您可以从数据库中获取数据作为流)。

标签: java csv hashset


【解决方案1】:
String[] values = csv.split(",");
Set<String> hashSet = new HashSet<String>(Arrays.asList(values));

【讨论】:

    【解决方案2】:

    其他 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 初始容量也是如此。
    • 正如 SagarG 指出的那样,StringTokenizer 现在不鼓励使用,因为它是一个遗留类。文档建议改用 java.util.regex 包 (docs.oracle.com/javase/7/docs/api/java/util/…)。
    • @PietroSaccardi 感谢您的回答,我不一定会在新代码中开始使用StringTokenizer,但是使用正则表达式很慢,这在问题和我的回答中都很清楚。我怀疑Scanner 可以用来避免遗留和缓慢的方面。
    【解决方案3】:
    Arrays.stream(csv.split(",")).collect(Collectors.toSet());
    

    【讨论】:

      【解决方案4】:

      你可以试试

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

      【讨论】:

        【解决方案5】:

        试试这个:

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

        但请注意,这可能是最简单的方法,但不一定是最佳方法。

        【讨论】:

          【解决方案6】:
          String[] array= csv.split(",");
          
          Set<String> set = new HashSet<String>(Arrays.asList(array));
          

          【讨论】:

            【解决方案7】:

            @Kayaman 当前接受的答案很好,但我要从 Java API 网页添加一些内容。由于没有足够的声誉,我无法将此作为评论添加到答案中。

            不鼓励使用 StringTokenizer。这里的 Java API 网页上提到了 http://docs.oracle.com/javase/7/docs/api/java/util/StringTokenizer.html

            StringTokenizer 是一个遗留类,出于兼容性原因保留,但不鼓励在新代码中使用它。建议任何寻求此功能的人改用 String 的 split 方法或 java.util.regex 包。

            【讨论】:

            • 这应该是对已接受答案的编辑,因为它本身不是答案。
            • 老兄彼得罗。它首先尝试将此作为评论添加到原始答案中,但系统说我没有足够的代表发表评论。然后我尝试编辑答案,但我的编辑被“同行”拒绝,指出这应该作为评论而不是作为编辑。最终,这是发表我想法的唯一方式。
            • 为了知识,我可以将其作为评论发布,然后结束您的任务:D
            • 大声笑。请继续。
            • 如果您熟悉您提到的java.util.regex 包,我建议您在答案中添加使用它的解决方案,以使其对其他读者有用。
            【解决方案8】:

            试试

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

            【讨论】:

              【解决方案9】:

              试试,

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

              也可以使用

              CollectionUtils

              collectionutils.addall();
              

              【讨论】:

                【解决方案10】:

                使用较新的 java 版本:

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

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2019-11-18
                  • 2018-08-16
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-12-18
                  • 2012-09-04
                  • 2013-02-04
                  相关资源
                  最近更新 更多