d2jsp
Log InRegister
d2jsp Forums > Off-Topic > Computers & IT > Programming & Development > Linkedhashset > On The Topic Of Generics
Add Reply New Topic New Poll
Member
Posts: 9,805
Joined: Jul 8 2008
Gold: 9.00
Jan 20 2015 08:22pm
I am trying to create a generic method that shuffles the elements of an arraylist without calling Collections.shuffle...

Code

public static <E> void shuffle (ArrayList<E> list){
int n = list.size();
Random rgen = new Random();
LinkedHashSet<Integer> randomSet = new LinkedHashSet<Integer>();
while (randomSet.size() < list.size()){
int next = rgen.nextInt(list.size());
randomSet.add(next);
}
System.out.println(randomSet); //for debugging
for(int i = 0; i < n; i++){
list.set(, list.get(i));
}

}


my question is, how do i use set() here so that the position in which each element from list.get(i) is determined by the LinkedHashSet, since it doesnt have a get method like arraylist

This post was edited by Wacko on Jan 20 2015 08:22pm
Member
Posts: 1,995
Joined: Jun 28 2006
Gold: 7.41
Jan 20 2015 08:45pm
Are you trying to do this in place? Then you need to swap based on the values in randomSet:

Code
//LinkedHashSet iterator() is guaranteed to be ordered
Iterator<Integer> iterator = randomSet.iterator();
for(int i = 0; iterator.hasNext(); i++)
{
int j = iterator.next();

E temp = list.get(i);
list.set(i, list.get(j));
list.set(j, temp);
}
Member
Posts: 9,805
Joined: Jul 8 2008
Gold: 9.00
Jan 20 2015 08:54pm
Quote (Minkomonster @ 20 Jan 2015 21:45)
Are you trying to do this in place? Then you need to swap based on the values in randomSet:

Code
//LinkedHashSet iterator() is guaranteed to be ordered
        Iterator<Integer> iterator = randomSet.iterator();
        for(int i = 0; iterator.hasNext(); i++)
        {
        int j = iterator.next();
       
        E temp = list.get(i);
        list.set(i, list.get(j));
        list.set(j, temp);       
        }


That worked wonderfully, however i dont know why :\ Ill have to read about the iterator class. I put a breakpoint on your for loop im interested to step through and see how this works
Member
Posts: 1,995
Joined: Jun 28 2006
Gold: 7.41
Jan 20 2015 09:09pm
Quote (Wacko @ Jan 20 2015 09:54pm)
That worked wonderfully, however i dont know why :\ Ill have to read about the iterator class. I put a breakpoint on your for loop im interested to step through and see how this works


It doesn't work perfectly though. It gives you a randomized list, but that list is not based on the order of randomSet like you asked. To do this you would need a bit more memory for storage. You could do something like this:

Code
//capture list's original size
int originalSize = list.size();
//LinkedHashSet iterator() is guaranteed to be ordered
Iterator<Integer> iterator = randomSet.iterator();
for(int i = 0; iterator.hasNext(); i++)
{
int j = iterator.next();
E temp = list.get(j);

//add a copy of the selected element to the end of this ArrayList
list.add(temp);

}

for(int i = 0; i < originalSize; i++ )
{
//remove the original order at the beginning of this ArrayList
list.remove(0);
}



It's pretty silly.
Member
Posts: 9,805
Joined: Jul 8 2008
Gold: 9.00
Jan 20 2015 09:15pm
Quote (Minkomonster @ 20 Jan 2015 22:09)
It doesn't work perfectly though. It gives you a randomized list, but that list is not based on the order of randomSet like you asked. To do this you would need a bit more memory for storage. You could do something like this:

Code
//capture list's original size
        int originalSize = list.size();
        //LinkedHashSet iterator() is guaranteed to be ordered
        Iterator<Integer> iterator = randomSet.iterator();
        for(int i = 0; iterator.hasNext(); i++)
        {
        int j = iterator.next();       
        E temp = list.get(j);
       
        //add a copy of the selected element to the end of this ArrayList
        list.add(temp);       
               
        }
       
        for(int i = 0; i < originalSize; i++ )
        {
        //remove the original order at the beginning of this ArrayList
        list.remove(0);
        }



It's pretty silly.


I should rephrase, it worked like this:
Code
public static <E> void shuffle (ArrayList<E> list){
int n = list.size();
Random rgen = new Random();
LinkedHashSet<Integer> randomSet = new LinkedHashSet<Integer>();
while (randomSet.size() < list.size()) {
int next = rgen.nextInt(list.size());
randomSet.add(next);
}
Iterator<Integer> iterator = randomSet.iterator();
for(int i = 0; iterator.hasNext(); i++)
{
int j = iterator.next();
E temp = list.get(i);
list.set(i, list.get(j));
list.set(j, temp);
}
}


Before Shuffle:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
After Shuffle:
[4, 2, 5, 1, 8, 7, 6, 0, 9, 3]

Thats the print statement, and after shuffle changes every time
Member
Posts: 1,995
Joined: Jun 28 2006
Gold: 7.41
Jan 20 2015 09:46pm
Quote (Wacko @ Jan 20 2015 10:15pm)
I should rephrase, it worked like this:
Code
public static <E> void shuffle (ArrayList<E> list){
        int n = list.size();
        Random rgen = new Random();
        LinkedHashSet<Integer> randomSet = new LinkedHashSet<Integer>();
        while (randomSet.size() < list.size()) {
            int next = rgen.nextInt(list.size());
            randomSet.add(next);
        }
        Iterator<Integer> iterator = randomSet.iterator();
        for(int i = 0; iterator.hasNext(); i++)
        {
            int j = iterator.next();
            E temp = list.get(i);
            list.set(i, list.get(j));
            list.set(j, temp);
        }
    }


Before Shuffle:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
After Shuffle:
[4, 2, 5, 1, 8, 7, 6, 0, 9, 3]

Thats the print statement, and after shuffle changes every time


Yes, but the ordering is not based on the set you created. The second piece of code I posted does it the way you originally intended.
Go Back To Programming & Development Topic List
Add Reply New Topic New Poll