java - How can I randomize the iteration sequence of a Set? -


i need use set collection.

each time start jvm run program, want iterate through items in set in randomly decided sequence.

the iteration sequence has nothing sequence in placed them in set, right?

so, do? how can randomize iteration sequence in set?

here method, , not randomize.

public static <t> void shuffle(set<t> set) {         list<t> shuffleme = new arraylist<t>(set);         collections.shuffle(shuffleme);         set.clear();         set.addall(shuffleme);     } 

what need randomizingiterator

set unordered, randomizing unordered collection doesn't make logical sense.

an ordered set ordered using comparator means has fixed order, can't shuffle it, has no meaning order determined comparator or compare() method.

set -> list allow shuffle contents of list , use custom randomizingiterator iterate across set.

example implementation :

link gist on github - testrandomizingiterator.java

import org.junit.test;  import javax.annotation.nonnull; import java.util.*;  public class testrandomzingiterator {     @test     public void testrandomiteration()     {         final set<string> set = new hashset<string>()         {             /** every call iterator() give possibly unique iteration order, or not */             @nonnull             @override             public iterator<string> iterator()             {                 return new randomizingiterator<string>(super.iterator());             }              class randomizingiterator<t> implements iterator<t>             {                 final iterator<t> iterator;                  private randomizingiterator(@nonnull final iterator<t> iterator)                 {                     list<t> list = new arraylist<t>();                     while(iterator.hasnext())                     {                         list.add(iterator.next());                     }                     collections.shuffle(list);                     this.iterator = list.iterator();                 }                  @override                 public boolean hasnext()                 {                     return this.iterator.hasnext();                 }                  @override                 public t next()                 {                     return this.iterator.next();                 }              /**              * modifying makes no logical sense, simplicity sake, implementation immutable.              * done, added complexity.              */             @override             public void remove()             {                 throw new unsupportedoperationexception("testrandomzingiterator.randomizingiterator.remove");             }             }         };          set.addall(arrays.aslist("a", "b", "c"));          final iterator<string> iterator = set.iterator();         while (iterator.hasnext())         {             system.out.println(iterator.next());         }     } } 

notes:

this straw man example, intention clear, use custom iterator custom iteration.

you can't normal iteration behavior back, doesn't seem problem use case.

passing the super.iterator() facade important, stackoverflowerror otherwise, because becomes recursive call if pass this .addall() or list() constructor.

hashset may appear ordered isn't guaranteed stay ordered, order depends on hashcode of objects , adding single object may reorder how contents order, contract of set interface order undefined , in particular hashset nothing more facade on backing map.keyset().

there other more supposedly light weight, more complex solutions use original iterator , try , keep track of has been seen, solutions aren't improvements on technique unless size of data excessively large, , looking @ on disk structures @ point.


Comments

Popular posts from this blog

python - Subclassed QStyledItemDelegate ignores Stylesheet -

java - HttpClient 3.1 Connection pooling vs HttpClient 4.3.2 -

SQL: Divide the sum of values in one table with the count of rows in another -