2

I have a list with values {"16","b","c","d","e","16","f","g","16","b"}; In this 16 and b are repeated so i want to delete all the entries of them and i need output as c, d, e, f, g. Below program works fine. Any better solutions?

public class Test {

 public static void main(String[] args) {

  ArrayList < String > l = new ArrayList < String > ();
  String[] str = {
   "16",
   "b",
   "c",
   "d",
   "e",
   "16",
   "f",
   "g",
   "16",
   "b"
  };


  for (String s: str) {
   l.add(s);
  }
  List ll = removeDups(l);
  l.removeAll(ll);
  System.out.println("Final List " + l);
 }

 private static List < String > removeDups(ArrayList < String > l) {
  List < String > ll = new ArrayList < String > ();
  for (String a: l) {
   int x = Collections.frequency(l, a);
   if (x > 1) {
    ll.add(a);
   }
  }
  return ll;
 }
}
Abhishek Agarwal
  • 1,190
  • 2
  • 19
  • 38
  • Kindly explain the code or comment it before posting a question on Stackoverflow. It helps everyone. – Abhishek Agarwal Jun 15 '17 at 03:39
  • As it is, the method `removeDups` should really be called `findDups` because it doesn't actually remove anything; it just _finds_ the items that are duplicated. If the line `l.removeAll(ll)` were moved inside of `removeDups`, _then_ `removeDups` would actually merit that name. – Kevin Anderson Jun 15 '17 at 03:57
  • Considering Collections.frequency is of the order `O(n)`, You can do better by using Hash maps. – Abhishek Agarwal Jun 15 '17 at 04:09
  • 1
    I'm voting to close this question as off-topic because it belongs on http://codereview.stackexchange.com – Dawood ibn Kareem Jun 15 '17 at 04:48
  • @DawoodibnKareem: This question is not duplicate of https://stackoverflow.com/questions/203984/how-do-i-remove-repeated-elements-from-arraylist. Neither is the solution. Solution suggested in the link mentioned by you will keep one entry for each repetitive element. But here the issue is to remove every element if it's repeating. It should NOT appear even `once` in the list. – Keyur Panchal Jun 16 '17 at 08:37
  • @KeyurPanchal The message you see is untrue. I didn't vote to close it as a duplicate. As my comment said, I voted to close it as off-topic; which it clearly is. So I'm not going to vote to re-open it. – Dawood ibn Kareem Jun 16 '17 at 09:51

4 Answers4

2

You can use Set to remove the duplicate elements from given array list.

Here is the sample code:

Set<String> myStrSet = new HashSet<String>();
Set<String> duplicateSet = new HashSet<String>();

         for(String str : myArrayList){
             if(myStrSet.contains(str)){
                  duplicateSet.add(str);
             } else {
                  myStrSet.add(str);
             }
         }

         for(String str : duplicateSet){
             myStrSet.remove(str);
         }

         for(String str : myStrSet){
             System.out.println("Print non-duplicate elements : " + str);
         }
Mohit Tyagi
  • 2,788
  • 4
  • 17
  • 29
  • 2
    I think OP wanted to remove _all_ instances of array elements which are duplicated; this leaves an instance of each duplicated item. – Kevin Anderson Jun 15 '17 at 03:59
  • Yes, I wanted to remove all occurences , Do not want to have any of the occurance if its repeated. – Sammeta naga srinivas Jun 15 '17 at 04:39
  • I don't know how this answer take up vote, It has more than one typo (myStrList and st) and It didn't remove duplicates. – Fady Saad Jun 15 '17 at 05:51
  • @Sammetanagasrinivas I have added new code, here first for loop will add duplicate elements into duplicateSet, now in second for loop we will remove the elements from myStrSet with the help of duplicateSet, so finally we will get a list which is free from all the occurrences of duplicate elements. – Mohit Tyagi Jun 19 '17 at 06:46
2

One way would be to use streams to find the frequency of each element:

Map<String, Long> counts = yourList.stream()
    .collect(Collectors.groupingBy(
        Function.identity(),     // keep the element as the key
        Collectors.counting())); // values will be the count 

Then, you could use removeIf to remove elements based on a condition, for which you'll use the frequencies map calculated above:

yourList.removeIf(elem -> counts.get(elem) > 1);

System.out.println(yourList); // [c, d, e, f, g]

Another way would be to first find out which values have duplicates and which ones are unique. For this, we can use a Map<String, Boolean>:

Map<String, Boolean> duplicates = new LinkedHashMap<>();
yourList.forEach(elem -> duplicates.compute(elem, (k, v) -> v != null));

Here I'm iterating the list and, for each element, I'm putting it into the map, computing the value as true if the element is already present as a key, or false if it's unique.

Then, you could use removeIf on the list, with a predicate that simply returns the value from the map:

yourList.removeIf(duplicates::get);

System.out.println(yourList); // [c, d, e, f, g]
fps
  • 33,623
  • 8
  • 55
  • 110
  • I think you mean below rite. This is also working fine.for(String s:l){ duplicates.put(s,(duplicates.containsKey(s)?true:false));} Iterator it= l.listIterator(); while(it.hasNext()){ String ss=(String)it.next(); if(duplicates.get(ss)){ it.remove(); } } – Sammeta naga srinivas Jun 16 '17 at 03:28
  • @Sammetanagasrinivas Yes, that seems to work too. You don't need the ternary operator. Just `duplicates.put(s, duplicate.containsKey(s));` is fine. – fps Jun 16 '17 at 11:34
1

You can compare index and lastIndex for each element. If they are same, the element is unique. We can filter those elements.

// imports
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

// sample code
String[] str = {"16","b","c","d","e","16","f","g","16","b"};
List<String> list = Arrays.asList(str); // List from the array
List<String> newList = new ArrayList<String>();
for(String myStr : list){
    if(list.indexOf(myStr) == list.lastIndexOf(myStr)){
        /*
         * This is a unique element as its index and lastIndex in list are same.
         * Add it to new list.
         */
        newList.add(myStr);
    }
}
// Freeing resources
str = null;
list = null;

System.out.println("Final List: "+ newList);
Keyur Panchal
  • 1,382
  • 1
  • 10
  • 15
0

I think this will do

public class DeleteDuplicates {

    public static void main(String[] args) {

        String[] str={"16","b","c","d","e","16","f","g","16","b"};
        List<String> l= new ArrayList<String>();
        Set<String> set = new HashSet<String>();

        for(String string : str) {

            if(set.add(string))
                l.add(string);
            else
                l.remove(string);
        }              

        System.out.println(l);
    }
}
Arun Sudhakaran
  • 2,167
  • 4
  • 27
  • 52