【问题标题】:Want non duplicate elements from list想要列表中不重复的元素
【发布时间】:2012-12-22 21:57:28
【问题描述】:

从下面的列表中,我只需要“哇”和“退出”。

List<String> list = new ArrayList();                
list.add("test");       
list.add("test");                   
list.add("wow");    
list.add("quit");
list.add("tree");
list.add("tree");

【问题讨论】:

标签: java list arraylist duplicates


【解决方案1】:

您可以检查Collection中某个元素的频率,并排除频率高于1的元素。

   List<String> list = new ArrayList<String>();
    list.add("test");       
    list.add("test");                   
    list.add("wow");    
    list.add("quit");
    list.add("tree");
    list.add("tree");
    for(String s: list){
        if(Collections.frequency(list, s) == 1){
            System.out.println(s);
        }

输出:

wow
quit

【讨论】:

  • 您的方式对于 i != 1 也适用,但我认为对于 i = 1,我更喜欢我发布的 indexOf() 方式。无论如何+1 ;)
  • 这和 indexOf 实现都在 O(n^2) 中运行。对于任何大的 n,这两个哈希示例都是可取的。
【解决方案2】:

这个 sn-p 应该给你留下一个集合 (output),它只包含你的列表中不重复的元素。

HashSet<String> temp = new HashSet<String>();
HashSet<String> output = new HashSet<String>();

for (String element : list)
{
    if (temp.contains(element)) output.remove(element);
    else
    {
        temp.insert(element);
        output.insert(element);
    }
}

在 O(n*log(n)) 时间内运行:对列表中的 n 个元素中的每一个元素进行一组对数运算(设置查找、插入等)。

【讨论】:

    【解决方案3】:

    还有第三种方式

    List result = new ArrayList();
    for(Object o : list){
       if(list.indexOf(o) == list.lastIndexOf(o))
       result.add(o);
    }
    

    【讨论】:

      【解决方案4】:

      您可以使用 HashMap impl 计算出现次数并仅选择出现一次的次数。

      例如

      void check(List<String> list)
      {
        Map<String,Integer> checker = new HashMap<String,Integer>();
        List<String> result = new ArrayList<String>();
        for(String value: list)
        {
          Integer count = checker.get(value); 
          if (count==null)
          {
            count = 0;
          }
          checker.put(value, ++count);
        }
        // now select only values with count == 1
        for(String value: checker.keySet())
        {
          if (checker.get(value) == 1)
          {
            result.add(value);
          }
        }
        System.out.println(result); 
      }
      

      【讨论】:

      • checker.put(value, count++); 应该是checker.put(value, ++count);
      【解决方案5】:

      Java 8+

      list.stream()                                              // Stream
          .filter(i -> Collections.frequency(list, i) == 1)      // Stream
          .collect(Collectors.toList())                          // List
          .forEach(System.out::println);                         // void
      

      它打印该列表中恰好出现一次的每个元素。

      详情:

      【讨论】:

        【解决方案6】:

        @ROMANIA_Engineer 的解决方案应该可以正常工作,但它确实隐藏了 O(n2) 复杂性,因为 Collections.frequency 是一个 O(n) 操作。

        仍然可以压缩到单个语句中的更有效的解决方案可能是计算每个项目出现的次数并仅过滤出现一次的项目:

        list.stream()
            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
            .entrySet()
            .stream()
            .filter(e -> e.getValue() == 1L)
            .map(Map.Entry::getKey)
            .forEach(System.out::println);
        

        【讨论】:

          【解决方案7】:

          这是一种没有流的 Java 8 方式:

          Map<String, Long> counts = new HashMap<>();
          list.forEach(word -> counts.merge(word, 1L, Long::sum));
          
          counts.values().removeIf(count -> count > 1);
          

          这首先迭代列表并将每个单词的频率存储在counts 映射中。为此,我使用Map.merge 方法,它将提供的值(在这种情况下为1L)与给定的键(word 这里)或使用提供的合并函数(Long::sum)组合一个给定值的存在值。

          然后,频率大于1 的单词会通过Collection.removeIf 方法从地图中删除。

          整个过程有O(n)时间复杂度。

          【讨论】:

            【解决方案8】:

            如果您愿意使用第三方库,可以将以下内容与Eclipse Collections 一起使用:

            List<String> list = Arrays.asList("test", "test", "wow", "quit", "tree", "tree");
            
            Set<String> set = Bags.mutable.withAll(list).selectUnique();
            
            System.out.println(set);
            

            输出:

            [wow, quit]
            

            您也可以直接构造Bag,而不是创建List,如下所示:

            MutableBag<String> bag = 
                Bags.mutable.with("test", "test", "wow", "quit", "tree", "tree");
            
            MutableSet<String> set = bag.selectUnique();
            

            注意:我是 Eclipse Collections 的提交者

            【讨论】:

              【解决方案9】:

              List aList = Arrays.asList("test", "test", “哇”、“哇”、“哇”);

              设置 hashSet = new HashSet(aList);

              hashSet.addAll(aList);

              现在您可以打印 HashSet 删除所有重复值

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2018-04-08
                • 2013-01-30
                • 1970-01-01
                • 2013-12-15
                • 2023-04-05
                相关资源
                最近更新 更多