ArrayIndexOutOfBoundsException

M

Mort

Stammgast
269
Hallo, mal ein Problem, dass wahrscheinlich nicht mit Android zu tun hat, mich aber schon länger nervt.
Ich habe für die "mischen über alle Ordner"-Funktion im MortPlayer folgenden Code (leicht gekürzt):
Code:
Random rand = new Random( new Date().getTime() );
int start = 0;
List<Integer> foldersDeck = new ArrayList<Integer>();
List<Integer> filesDeck = new ArrayList<Integer>();
        
for ( alle Dateien in den ersten, zufälligen Ordnern ) {
    foldersDeck.add( shuffleFolders[i] );
    filesDeck.add( ii );
}
        
int fileCount = Math.min(maxFilesForShuffleAll, filesDeck.size());
shuffleFolders = new int[fileCount];
shuffleFiles   = new int[fileCount];

/* etwas Handling um aktuelle und ggf. gewählte nächste Datei an den
Anfang der Liste zu setzen */

for ( int i = start; i < fileCount && filesDeck.size() > 0; i++ ) {
    pos = rand.nextInt( filesDeck.size() );
    shuffleFolders[i] = foldersDeck.get(pos);
    shuffleFiles[i]   = filesDeck.get(pos);
    foldersDeck.remove(pos);
    filesDeck.remove(pos);
}
(shuffleFolders und shuffleFiles sind private int[]-Properties der Klasse)

Jetzt bekomme ich gelegentlich Fehlermeldungen, die eine ArrayIndexOutOfBoundsException bei "shuffleFolders = foldersDeck.get(pos);" enthalten. Ich kann mir aber nicht erklären, wie das zustande kommen kann, und selbst konnte ich den Fehler noch nicht nachvollziehen. Übersehe ich irgendwas wichtiges?
Eigentlich müssten foldersDeck und filesDeck gleich groß sein, sie werden an nur einer Stelle gleichzeitig gefüllt. rand.nextInt dürfte keinen Wert über dem höchsten Index liefern. i kann nicht größer als fileCount werden, das kurz vorher als Array-Größe verwendet wurde. Wo kommt da ein ungültiger Index her???
(Dass shuffeFiles/Folders zwischendurch per Multithreading auf andere Arrays zeigen ist übrigens auch sehr unwahrscheinlich, der Code läuft in einem synchronized-Block und wird ohnehin nicht allzu oft aufgerufen).
 
was sein könnte

pos = rand.nextInt( filesDeck.size() );

pos kann hier gleich der size sein

beim get müsste es aber dann pos-1 sein, da 0 basiert

beispiel

filesDeck hat 10 einträge

pos = 10 ( weil .size() )

get(10) ist aber zuviel, da 0-9

lg
 
swordi schrieb:
pos = rand.nextInt( filesDeck.size() );

pos kann hier gleich der size sein
Laut JavaDoc eigentlich nicht: "Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive), drawn from this random number generator's sequence."
 
ok

aber war ein versuch wert ;)
 
Poste mal deine Stacktrace....
 
ko5tik schrieb:
Poste mal deine Stacktrace....
Der hilft an der Stelle vermutlich nicht viel. Die Exception ist direkt an der Stelle ohne "Zwischenklassen", danach kommt der übliche Kram bis zum Aufruf, z.B.
Code:
java.lang.ArrayIndexOutOfBoundsException
    de.stohelit.folderplayer.playback.FolderManager.fillShuffleAll(FolderManager.java:1686)
    de.stohelit.folderplayer.playback.FolderManager.gotoTrack(FolderManager.java:1137)
    de.stohelit.folderplayer.playback.PlaybackService$7.gotoTrack(PlaybackService.java:1592)
    de.stohelit.folderplayer.TrackList$7.onClick(TrackList.java:427)
    com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:876)
    ....
 
Ich kenne mich zwar mit Android-Java noch nicht aus, aber in "normalem" Java (J2SE) würde ich einfach mal ein
Code:
System.out.println("[FONT=monospace]filesDeck.size() = [/FONT]" + filesDeck.size() 
                 + ", foldersDeck.size() = " + foldersDeck.size() 
                 + ", pos = " + pos);
nach der Änderung der pos-Variable einfügen und schauen, bei welchen Werten diese Exception kommt. Erfahrungsgemäß vertut man sich da gern mal um 1.

Gruß,
Blalasaadri
 
Ist die erste for-Schleife sehr komplex oder geheim? Ich seh da nämlich ein Array in dem Ausschnitt, den du gepostet hast, und die beiden in der zweiten Schleife würd ich fast ausschließen.
Code:
for ( alle Dateien in den ersten, zufälligen Ordnern ) {
    foldersDeck.add( shuffleFolders[i] );
    filesDeck.add( ii );
}
 
Kranki schrieb:
Ist die erste for-Schleife sehr komplex oder geheim?
Ne, das nicht. Nur etwas verwirrend, und eigentlich geht's an der Stelle ja nur darum, dass die beiden Deck-Arrays gleichzeitig an derselben Stelle gefüllt werden.

Code:
        fillShuffleFolders(); // füllt shuffleFolders mit den Ordner-Indizes in zufälliger Reihenfolge. Nach dem Füllen der Decks wird dieser Array "weggeworfen" (out of scope via folderArray = new ...)

        for ( int i = 0; i < shuffleFolders.length && foldersDeck.size() < maxFilesForShuffleAll*2; i++ ) {
            FolderInfo folder = foldersWithFiles.get( shuffleFolders[i] );
            for ( int ii = 0; ii < folder.getPlayableFiles(); ii++ ) {
                // aktuelles und nächstes File werden hinterher
                // an den Anfang verfrachtet, deshalb hier ignoieren
                if ( ( shuffleFolders[i] != currentFolderIndex 
                        || ii != currentFileIndex )
                    && ( nextFileIndex == -1
                            || shuffleFolders[i] != nextFolderIndex 
                            || ii != nextFileIndex )
                    ) {
                    foldersDeck.add( shuffleFolders[i] );
                    filesDeck.add( ii );
                }
            }
        }
 
Zurück
Oben Unten