user1959531
user1959531

Reputation: 81

Want non duplicate elements from list

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

Upvotes: 6

Views: 9401

Answers (11)

Rohit Tingare
Rohit Tingare

Reputation: 21

You can use Java 8 Stream api feature to create different list with only unique elements from original list. Please see below code for reference.

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

List<String> uniqueElements = list.stream().filter(element- 
>Collections.frequency(list,element)==1).toList();

Above code will initialize 'uniqueElements' list with unique elements from 'list'.

Upvotes: 0

John
John

Reputation: 47

Easily clean a list using a lambda:

list.removeIf(element -> Collections.frequency(list, element) > 1);

Upvotes: 1

sahil
sahil

Reputation: 21

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

Set hashSet = new HashSet(aList);

hashSet.addAll(aList);

now you can print HashSet all the duplicates values removed

Upvotes: 1

Donald Raab
Donald Raab

Reputation: 6686

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

Upvotes: 0

fps
fps

Reputation: 34460

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.

Upvotes: 2

Mureinik
Mureinik

Reputation: 311163

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

Upvotes: 1

ROMANIA_engineer
ROMANIA_engineer

Reputation: 56626

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:

Upvotes: 1

user1697575
user1697575

Reputation: 2848

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

Upvotes: 3

PermGenError
PermGenError

Reputation: 46408

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

Upvotes: 8

Nabil A.
Nabil A.

Reputation: 3400

And a Third way

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

Upvotes: 2

Wug
Wug

Reputation: 13196

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.

Upvotes: 4

Related Questions