find the index of unique values in LinkedHashSet

265 Views Asked by At

I'm using LinkedHashSet to get all the unique values from an ArrayList.

My code looks as following:

Set<String> set = new LinkedHashSet<>( filteredTitles );
filteredTitles.clear();
filteredTitles.addAll( set );

For example if filteredTitles was equals to ["a","b","c","a"] It will return me ["a","b","c"].

How can I get the index of the unique values? for example here [1,2,3] since 4 is not unique already.

Thank you

3

There are 3 best solutions below

0
WJS On BEST ANSWER

How can I get the index of the unique values?

Here is one way of doing it using a map.

  • the map maintains the Object as key and index as value.
  • A set maintains a record of previous added objects to ensure only unique ones are added.
List<String> list = List.of("a","b","e","c","a","d","f","e","f","e","g");

 
Set<String> seen = new HashSet<>();
Map<String,Integer> uniquePair = new HashMap<>();
for (int i = 0; i < list.size(); i++) {
    String str = list.get(i);
    if (seen.add(str)) { // if not seen already, add to map
       uniquePair.put(str, i);
       continue;
    }
    uniquePair.remove(str); // oops, not unique, remove from map.
}
  
uniquePair.entrySet().forEach(System.out::println);

prints

b=1
c=3
d=5
g=10
1
azro On

You can, for each unique element, retrieve it's first index in the first list. Also indexing starts at 0

List<String> titles = Arrays.asList("a", "b", "c", "a", "e");
List<String> uniqueTitles = new ArrayList<>(new LinkedHashSet<>(titles));

List<Integer> indices = uniqueTitles.stream().map(titles::indexOf).collect(Collectors.toList());

System.out.println(uniqueTitles); // [a, b, c, e]
System.out.println(indices);      // [0, 1, 2, 4]
0
Andy Turner On

Rather than simply copying the list into the LinkedHashSet, you can build it up along with the list of indices:

Set<String> set = new LinkedHashSet<>();
List<Integer> firstOccurrences = new ArrayList<>();

for (int i = 0; i < filteredTitles.size(); ++i) {
  if (set.add(filteredTitles.get(i))) {
    firstOccurrences.add(i);
  }
}