Want non duplicate elements from list

别等时光非礼了梦想. 提交于 2019-12-10 13:45:34

问题


From following list I need only 'wow' and 'quit'.

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

回答1:


you can check the frequency of an element in the Collection and rule out the elements which have frequency higher than 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);
        }

Output:

wow
quit



回答2:


This snippet should leave you with a set (output) which contains only non-duplicated elements of your list.

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

Operates in O(n*log(n)) time: one set of logarithmic operations (set lookups, inserts, etc) for each of the n elements in the list.




回答3:


You can use HashMap impl to count occurences and select only onces that occur once.

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



回答4:


And a Third way

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



回答5:


@ROMANIA_Engineer's solution should work just fine, but it does hide an O(n2) complexity in it, since Collections.frequency is an O(n) operation.

A more efficient solution that can still be squeezed in to a single statement could be to count how many times each item occurs and filter just items that appear once:

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



回答6:


Java 8+

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

It prints every element from that list that appears exactly once.

Details:

  • lambda expressions
  • Stream interface
  • Collections class



回答7:


Here is a Java 8 way without streams:

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

counts.values().removeIf(count -> count > 1);

This first iterates the list and stores the frequency of each word in the counts map. For this I'm using the Map.merge method, which either associates the provided value (1L in this case) with the given key (word here) or uses the provided merge function (Long::sum) to combine an existent value with the given one.

Then, words with a frequency greater than 1 are removed from the map via the Collection.removeIf method.

The whole process has O(n) time complexity.




回答8:


If you're open to using a third-party library, the following can be used with 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);

Outputs:

[wow, quit]

You can also construct a Bag directly instead of creating a List as follows:

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

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

Note: I am a committer for Eclipse Collections



来源:https://stackoverflow.com/questions/14225302/want-non-duplicate-elements-from-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!