想要列表中的非重复元素

时间:2013-01-08 22:41:11

标签: java list arraylist duplicates

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

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

9 个答案:

答案 0 :(得分:5)

您可以检查集合中元素的频率,并排除频率高于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

答案 1 :(得分:3)

此代码段应该为您留下一个集合(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个元素的一组对数运算(设置查找,插入等)。

答案 2 :(得分:3)

您可以使用HashMap impl对事件进行计数,并仅选择出现一次的事件。

e.g。

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

答案 3 :(得分:2)

第三种方式

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

答案 4 :(得分:1)

@ ROMANIA_Engineer的解决方案应该可以正常工作,但它确实隐藏了O(n 2 )复杂性,因为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);

答案 5 :(得分:1)

列表aList = Arrays.asList(“ test”,“ test”, “哇”,“哇”,“哇”);

设置hashSet = new HashSet(aList);

hashSet.addAll(aList);

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

答案 6 :(得分:0)

Java 8 +

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

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

详细说明:

答案 7 :(得分:0)

这是一种没有流的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相关联)或使用提供的合并函数({ {1}})将现有值与给定值组合。

然后,通过Collection.removeIf方法从地图中删除频率大于Long::sum的字词。

整个过程的时间复杂度为1

答案 8 :(得分:0)

如果您愿意使用第三方库,则可以在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的提交者