Vasu
Vasu

Reputation: 22452

Replace HashSet contents without creating new HashSet Object

I have to manipulate strings present under a big HashSet Object and I would like to know if there is any possibility of manipulating existing HashSet object with out creating a new HashSet object

Below is my current logic, in which, I wanted to avoid the creation of 2nd HashSet (set2 object).

HashSet<String> set1 = new HashSet<String>();
set1.add("AB.12");
set1.add("CD.34");
set1.add("EF.56");
set1.add("GH.78");

HashSet<String> set2 = new HashSet<String>();
for(String data : set1) {
    set2.add(data.substring(0,2));
}

P.S.: The reason for going for a Set is to avoid duplicate entries (come from different source).

Upvotes: 1

Views: 1215

Answers (4)

elizzmc
elizzmc

Reputation: 125

Elements in a HashSet should not be altered to maintain the integrity of the set. You can think of them as immutable elements.

And since the order of a HashSet is not defined or constant over time, it won't be possible to add and remove elements simultaneously without potentially colliding with new elements.

However, if you're trying to conserve memory, you can simultaneously remove from set1 and add to set2.

Iterator iter = set1.iterator();

while(iter.hasNext()){
    set2.add(iter.next().substring(0, 2));
    iterator.remove();
}

Upvotes: 3

James Wierzba
James Wierzba

Reputation: 17568

There isn't a perfect solution to your problem. The issue is that a Set by definition does not allow indexing. Coupled with the fact that String is immutable, modifying the data is not feasible.

I think you should consider changing 2 things.

  1. Use a data structure that allows you to replace elements (such as a List)

2. Use a mutable datatype, possibly creating your own class as the data type element (as Victor suggested in the comments).

This will break the internals of the HashSet because the index was created by hashing the element, if the element changes, it may disappear.

Upvotes: 1

sdgfsdh
sdgfsdh

Reputation: 37121

Java Set does not provide ordered access so you cannot step through one by one to do a replacement.

With a List, you could do:

for (int i = 0; i < list.count(); i++) {

    list.set(i, list.get(i).substring(0, 2));
}

Note that building a new Set object is not a problem, unless you have a massive data-set.


Another option is to use a Stack:

final Stack<String> toProcess = new Stack<>();

for (final String i : set1) {

    toProcess.push(i);
}

set1.clear();

while (!toProcess.isEmpty()) {

    set1.add(toProcess.pop().substring(0, 2));
}

Upvotes: 1

Kishore Reddy
Kishore Reddy

Reputation: 926

If you really thinking about wastage of memory then you can do like :

   HashSet<String> set2 = new HashSet<String>();

   Iterator<String> ite = set1.iterator();
   while(ite.hasNext()){
         String data = ite.next();
         ite.remove(); //look this
        set2.add(data.substring(0,2));
   }

Upvotes: 1

Related Questions