6

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

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

9 回答 9

7

您可以检查 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
于 2013-01-08T22:44:23.297 回答
4

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

于 2013-01-08T22:44:37.990 回答
3

您可以使用 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); 
}
于 2013-01-08T22:52:56.260 回答
2

第三种方式

List result = new ArrayList();
for(Object o : list){
   if(list.indexOf(o) == list.lastIndexOf(o))
   result.add(o);
}
于 2013-01-08T22:46:01.733 回答
2

这是一种没有流的 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)时间复杂度。

于 2018-03-22T21:40:30.403 回答
1

List aList = Arrays.asList("test", "test", "wow", "wow", "wow");

设置 hashSet = new HashSet(aList);

hashSet.addAll(aList);

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

于 2020-09-24T16:40:11.073 回答
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);
于 2018-03-22T21:02:17.960 回答
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直接构造 a 而不是创建 a List,如下所示:

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

MutableSet<String> set = bag.selectUnique();

注意:我是 Eclipse Collections 的提交者

于 2019-10-28T05:48:52.687 回答
0

Java 8+

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

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

细节:

于 2016-11-12T16:44:38.687 回答