Reputation: 7
I have below ArrayList
["P", "a", "y", "P", "a", "l", "I", "n", "d", "i", "a"]
Expected result [y, l, I, n, d, i]
I want to remove all duplicates, including original value. For example: 'P' is duplicate. If i use set, it will remove duplicates and one 'P' will display. i want to remove all the 'P'.
I have tried below code. But its validating only if there is even set of chars,
ArrayList<Character> unique = new ArrayList<Character>();
for (Character c : b) {
if (unique.contains(c)) {
unique.remove(c);
} else {
unique.add(c);
}
}
This code validates and removing 'P', but not 'a'. Because 'a' listed 3 t
Upvotes: 0
Views: 188
Reputation: 4667
A fun way you can do this without Java 8 streams is to make an int
array of size 128
that will hold the counts of each occurrence at the index of the character value.
For example, if a
appears 3 times, array[97]
will equal 3
, where 97
is the Ascii value of a
(I know technically ascii is not used).
The downside to this implementation is it cannot handle any other characters above the first 128 characters in the ascii table. Though you can extend it accordingly.
Here is what this would look like:
public static void main(String[] args) {
ArrayList<Character> list = new ArrayList<>();
list.add(Character.valueOf('P'));
list.add(Character.valueOf('t'));
list.add(Character.valueOf('L'));
list.add(Character.valueOf('L'));
list.add(Character.valueOf('b'));
list.add(Character.valueOf('P'));
list.add(Character.valueOf('c'));
int [] lookup = new int[128];
//Build the lookup table
for (char c : list) {
lookup[c]++;
}
//Remove the values that are greater than 1 in the lookup table
for (int j = 0; j < lookup.length; j++) {
int count = lookup[j];
for (int k = 0; k < count && count > 1; k++) {
list.remove(Character.valueOf((char) j));
}
}
}
The code basically breaks down to two main parts:
Building the lookup table.
Removing values from the list using the lookup table as reference.
Now this is obviously more complicated than a solution with Map
, Set
, or using streams would be, but I figured with your requirements you may not be able to use stream either.
Upvotes: 0
Reputation: 105
This may help
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class RemoveDuplicates {
public static void main(String[] args) {
String string = "PayPalIndia";
List<Character> strings = string.chars().mapToObj(c -> (char) c).collect(Collectors.toList());
Set<Character> set = new HashSet<>();
Iterator<Character> iterator = strings.iterator();
Set<Character> invalid = new HashSet<>();
while (iterator.hasNext()) {
Character c = iterator.next();
if (set.contains(c)) {
iterator.remove();
invalid.add(c);
} else {
set.add(c);
}
}
System.out.println("Duplicate parents");
invalid.forEach(System.out::print);
System.out.println();
strings.removeAll(invalid);
System.out.println("=============");
System.out.println("After removing Duplicates...");
strings.forEach(System.out::print);
System.out.println();
}
}
Upvotes: 0
Reputation: 4140
First it count occurence of every char then filter out by number of occurrence (only with one occurence).
List<Character> input = Arrays.asList('P', 'a', 'y', 'P', 'a', 'l', 'I', 'n', 'd', 'i', 'a');
List<Character> collect = input.stream()
.collect(Collectors.groupingBy(p -> p, Collectors.counting()))
.entrySet().stream()
.filter(e -> e.getValue() == 1)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
System.out.println(collect);
The older version without streams can be written like that:
// create Map with count occurence
Map<Character, Integer> countMap = new HashMap<>();
for (Character value : input) {
if (!countMap.containsKey(value)) {
countMap.put(value, 1);
} else {
countMap.put(value, countMap.get(value) + 1);
}
}
// filter Map
List<Character> collect = new ArrayList<>();
for (Map.Entry<Character, Integer> value : countMap.entrySet()) {
if( value.getValue() == 1) {
collect.add(value.getKey());
}
}
System.out.println(collect);
Upvotes: 3
Reputation: 349
Try this
ArrayList charsList = new ArrayList<>(Arrays.asList('P', 'a', 'y', 'P', 'a', 'l', 'I', 'n', 'd', 'i', 'a'));
List listWithoutDuplicates = charsList.stream().distinct().collect(Collectors.toList());
Upvotes: -1
Reputation: 8686
Try this approach:
public static void main(String[] args) {
List<Character> unique = Arrays.asList('P', 'a', 'y', 'P', 'a', 'l', 'I', 'n', 'd', 'i', 'a');
List<Character> result = unique.stream().filter(i1 -> unique.stream().filter(i2 -> i1.equals(i2)).count() == 1).collect(Collectors.toList());
System.out.println(result);
}
Output is: [y, l, I, n, d, i]
Upvotes: 1