Piszę program do jakiegoś oprogramowania quizowego. Mam klasę pytań zawierającą ArrayLists dla pytania, odpowiedzi, opcji, znaków i znaków ujemnych. Coś takiego:
class question
{
private ArrayList<Integer> index_list;
private ArrayList<String> question_list;
private ArrayList<String> answer_list;
private ArrayList<String> opt1_list;
private ArrayList<String> opt2_list;
}
Chcę tasować wszystkie pytania, ale aby pytania były tasowane, wszystkie obiekty muszą być tasowane. Podszedłbym do tego problemu w następujący sposób:
Po pierwsze, nie użyłbym tego projektu i nie używałbym String ArrayList<String>
jako zmiennych instancji, a następnie użyłbym Collections.shuffle
metody do losowego przesyłania obiektów. Ale mój zespół nalega na ten projekt.
Teraz klasa pytań zawiera coraz większą liczbę ArrayLists w miarę wprowadzania danych do pytań. Jak teraz tasować pytania?
java
collections
użytkownik1369975
źródło
źródło
Odpowiedzi:
Twój zespół ma typowy problem: odmowa obiektu .
Zamiast klasy, która zawiera jedno pytanie ze wszystkimi powiązanymi z nią informacjami, próbujesz utworzyć klasę o nazwie,
question
która zawiera wszystkie pytania w jednym wystąpieniu.To zły sposób, aby to zrobić i komplikuje to, co próbujesz zrobić dużo ! Sortowanie (i tasowanie) równoległych tablic (lub list) to paskudna sprawa i nie ma dla nich wspólnego API, po prostu dlatego, że zwykle w ogóle chcesz tego uniknąć .
Sugeruję restrukturyzację kodu w następujący sposób:
W ten sposób tasowanie pytania staje się banalne (używanie
Collections.shuffle()
):źródło
Ty nie. Tworzysz kolejną listę / kolejkę indeksów i przetasujesz ją. Następnie iterujesz w dół indeksy, które określają kolejność „przetasowania” innych kolekcji.
Nawet poza scenariuszem, w którym rzeczy są rozdzielone, oddzielna kolekcja zamawiania zapewnia szereg korzyści (równoległość, szybkość ponownego umieszczania oryginalnej kolekcji jest kosztowna itp.).
źródło
Zgadzam się z innymi odpowiedziami, że poprawnym rozwiązaniem jest użycie odpowiedniego modelu obiektowego.
W rzeczywistości jednak dość łatwo jest tasować wiele list w identyczny sposób:
źródło
Utwórz klasę
Question2
:Następnie utwórz funkcję odwzorowującą
question
naArrayList<Question2>
, użyjCollection.Shuffle
dla tego wyniku i utwórz drugą funkcję do odwzorowania zArrayList<Question2>
powrotemquestion
.Następnie idź do swojego zespołu i spróbuj przekonać ich, że użycie
ArrayList<Question2>
zamiast zamiastquestion
znacznie poprawiłoby ich kod, ponieważ zaoszczędziłoby im to wiele niepotrzebnych konwersji.źródło
Moja oryginalna naiwna i zła odpowiedź:
Aktualizacja:
Dzięki za the_lotus za wskazanie artykułu o horrorze kodowania. Teraz czuję się znacznie mądrzejszy :-) W każdym razie Jeff Atwood pokazuje również, jak to zrobić dobrze, używając algorytmu Fisher-Yates :
Główną różnicą jest to, że każdy element jest zamieniany tylko raz.
I podczas gdy inne odpowiedzi poprawnie wyjaśniają, że twój model obiektowy jest wadliwy, możesz nie być w pozycji, aby go zmienić. Tak więc algorytm Fisher-Yates rozwiązałby twój problem bez zmiany modelu danych.
źródło