Methoden Collections.shuffle mit bestimmtem Startwert?

DerTilo

Neues Mitglied
Hallo liebe Coder 😀,

ich wollte in einem Programm zwei ArrayLists aufeinander abgestimmt vermischen, sodass quasi beide in die selbe "Aufstellung" gebracht werden:

Code:
        ArrayList list1 = new ArrayList();
        ArrayList list2 = new ArrayList();

        for (int i = 0; i < 6; i++){
            list1.add("test" + i);
            list2.add("test" + i);
        }
        System.out.println("Inhalt von list1: " + list1);
        System.out.println("Inhalt von list2: " + list2);

        Collections.shuffle(list1);
        Collections.shuffle(list2);

        System.out.println("Inhalt von list1: " + list1);
        System.out.println("Inhalt von list2: " + list2);

Kann man der Methode einen Startwert wie bei Random geben oder sie sonst irgendwie gleich mischen?
Hoffe, die Frage war nicht zu blöd, ich bin Anfänger xD
 
Morjen, also ich muss gleich dazu sagen, dass man so nicht mischen sollte, weil man so nicht mischen sollte, aber für deine Zwecke wahrscheinlich vollkommen ausreichend:
Java:
    public static void main(String[] args) throws IOException {
        ArrayList<Integer> list1 = new ArrayList<>();
        list1.add(0);
        list1.add(1);
        list1.add(2);
        list1.add(3);
        list1.add(4);
        for (int k = 0; k < 2; k++) {
        for (int i = 5; i < 7; i++) {
            for (int j = 0; j < 3; j++) {
                ArrayList<Integer> list2 = new ArrayList<>(list1);
                mischen(list2, i);
                System.out.println("list2 = " + list2);
            }
        }
        }
        System.out.println("list1 = " + list1);
    }

    /**
     * Just for debug-purposes...
     *
     * @param list
     */
    static void mischen(List list, long seed) {
        Random r = new Random(seed);
        Object[] os = list.toArray();
        for (int i = 0; i < os.length; i++) {
            int j = r.nextInt(os.length);
            Object o = os[i];
            os[i] = os[j];
            os[j] = o;
        }
        for (int i = os.length - 1; i >= 0; i--) {
            int j = r.nextInt(os.length);
            Object o = os[i];
            os[i] = os[j];
            os[j] = o;
        }
        list.clear();
        list.addAll(Arrays.asList(os));
    }

Code:
list2 = [3, 0, 4, 2, 1]
list2 = [3, 0, 4, 2, 1]
list2 = [3, 0, 4, 2, 1]
list2 = [1, 4, 3, 0, 2]
list2 = [1, 4, 3, 0, 2]
list2 = [1, 4, 3, 0, 2]
list2 = [3, 0, 4, 2, 1]
list2 = [3, 0, 4, 2, 1]
list2 = [3, 0, 4, 2, 1]
list2 = [1, 4, 3, 0, 2]
list2 = [1, 4, 3, 0, 2]
list2 = [1, 4, 3, 0, 2]
list1 = [0, 1, 2, 3, 4]

Wenn du jetzt ein Kartenspiel hast und ein Spieler X, naja du kannst dir vorstellen, was damit alles möglich ist...

Andererseits werden ja auch Zufallswelten mit "Seed" so erstellt. 😀
 
Morjen, also ich muss gleich dazu sagen, dass man so nicht mischen sollte, weil man so nicht mischen sollte, aber für deine Zwecke wahrscheinlich vollkommen ausreichend:
Hast du mal in die Implementierung von shuffle geguckt, da steht so ziemlich das gleiche, wie du hier machst...

Java:
    public static void shuffle(List<?> list) {
        Random rnd = r;
        if (rnd == null)
            r = rnd = new Random(); // harmless race.
        shuffle(list, rnd);
    }

    @SuppressWarnings({"rawtypes", "unchecked"})
    public static void shuffle(List<?> list, Random rnd) {
        int size = list.size();
        if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
            for (int i=size; i>1; i--)
                swap(list, i-1, rnd.nextInt(i));
        } else {
            Object arr[] = list.toArray();

            // Shuffle array
            for (int i=size; i>1; i--)
                swap(arr, i-1, rnd.nextInt(i));

            // Dump array back into list
            // instead of using a raw type here, it's possible to capture
            // the wildcard but it will require a call to a supplementary
            // private method
            ListIterator it = list.listIterator();
            for (int i=0; i<arr.length; i++) {
                it.next();
                it.set(arr[i]);
            }
        }
    }

@DerTilo
Fülle doch Array Nr 1 und dann shuffel ist, danach erzeugst du für das zweite Array eine Kopie vom ersten.
 
@Jardcore : Jein, so halb hatte ich da etwas in Erinnerung,
ABER:
"sie" laufen nur bis i>1,
ich durchlaufe 2mal,
es muss nicht extra eine neue Liste erstellt werden, um alle Elemente einer Liste hinzuzufügen,
UND:
es gibt wissenschaftliche Abhandlungen darüber, wie eine Liste sortiert wird oder sollte.

ABER: Das Mischen wird nicht zeitkritisch sein UND "Qualitätsgüte" wird ausreichen???

Dennoch, vielen Danke für das Zitat, habe etwas von gelernt
 
Die frage ist nicht immer wie etwas wissenschaftlich gemacht wird, sondern ob es den Ansprüchen genügt und die Aufgabe erfüllt. Code sollte so geschrieben werden, das er wartbar ist. Performance wird erst beachtet, wenn es zu Problemen kommt.... und aus meiner Erfahrung kommt es nie zu den Problemen die man theoretisch alle gelernt haben soll.

Also ja, die Qualität und vor Allem die Lesbarkeit ist durch ein shuffel() deutlich höher.
 
Ehrlich, es wird exakt das Gleiche gemacht, nur die Indizes sind etwas anders:
Java:
            for (int i=size; i>1; i--)
                swap(arr, i-1, rnd.nextInt(i));
und es wird noch der Trick mit ListIterator.set() genutzt, wodurch einige Operationen gespart werden. (steht ja auch dabei)

Also gerne darf er die Methode mischen() oben leicht modifizieren und verwenden. (wenn ich weiß, das n Elemente schon gemischt sind, brauche ich nur noch n-1 Elemente ab n+1 oder n-1 betrachten 😉 ) [so nähern wir uns der Invariante, obwohl "schon/bereits gemischt" im wissenschaftlichen Sinne etwas ungenau ist 😀 ]
 
Habe im Detail nicht mitgelesen, aber Sachen nach den selben Vorgaben zu mischen führt nach meinem Verständnis das Wort Mischen ad absurdum. Dann kann er eigentlich direkt die Methode sort() benutzen und das Interface comparable.

Korrigiert mich wenn ich mit meinem Gedanken da falsch liege.
 
So wird in der Praxis nun mal gemischt. Warum O (n*n), wenn es auch O (n) tut?
2. Schon mal die Überschrift des Themas gelesen? Bei gleichbleibendem Seed möchte er gleichbleibende "Sortierung". (Bearbeitung: Mischung, aber das klingt wie Drogendealer ^^)
 

Zurück
Oben