التكرار العكسي من خلال Arraylist يعطي IndexOutofBoundSexception
سؤال
عندما أعرب التكرار فوق قائمة صفيف أحصل على فهرسة حاولت إجراء التكرار إلى الأمام ولا توجد مشكلة. أتوقع وأعلم أن هناك خمسة عناصر في القائمة. الرمز أدناه:
Collection rtns = absRtnMap.values();
List list = new ArrayList(rtns);
Collections.sort(list);
for(int j=list.size();j>0;j=j-1){
System.out.println(list.get(j));
}
التكرار إلى الأمام - الذي يعمل بشكل جيد، ولكن ليس مفيدا بالنسبة لي:
for(int j=0;j<list.size();j++){
System.out.println(list.isEmpty());
System.out.println(list.get(j));
} // this worked fine
الخطأ:
Exception in thread "Timer-0" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
at java.util.ArrayList.RangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at model.Return.getReturnMap(Return.java:61)
at controller.Poller$1.run(Poller.java:29)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)
أيضا إذا كان أي شخص يعرف عن تصميم أفضل للتكرار العكسي، سأكون سعيدا بمحاولة ذلك.
المحلول
بدء التكرار في list.size() - 1
لأن الصفيف (أو ArrayList
) يتم ترقيم العناصر من 0 حتى 1 أقل من حجم القائمة. هذا هو المصطلح القياسي إلى حد ما:
for (int j = list.size() - 1; j >= 0; j--) {
// whatever
}
لاحظ أن التكرار الخاص بك إلى الأمام يعمل لأنه يتوقف قبل الوصول إلى list.size()
.
نصائح أخرى
تجنب الفهارس تماما؟ ماذا عن:
for (ListIterator iterator = list.listIterator(list.size()); iterator.hasPrevious();) {
final Object listElement = iterator.previous();
}
أعلم أن هذا سؤال قديم، ولكن جافا يحتوي على Collections.reverse( List<T> )
طريقة. لماذا لا تعكسها فقط وتؤدي التكرار؟
الطريقة الأكثر أناقة هي عكس الصفيف ثم استخدام جهاز كمتقل مباشر (أو حتى ضمني):
Collections.reverse(arrayList);
for (Object item : arrayList) {
...
}
القائمة. الحجم () تجاوز آخر فهرس المسموح به.
for(int j = list.size() - 1; j >= 0; j--) {
System.out.println(list.get(j));
}
صفائف Java هي صفر مفهرسة. سيكون عليك تعيين J = List.Size () - 1 والمتابعة حتى ي = 0.
إذا كانت القوائم صغيرة إلى حد ما، بحيث تكون الأداء ليست مشكلة حقيقية، يمكن للمرء استخدام reverse
- من. Lists
-Class في Google Guava
. وبعد غلة جميلة for-each
-Code، وتبقى القائمة الأصلية نفس الشيء. أيضا، يتم دعم القائمة العكسية من قبل القائمة الأصلية، لذلك سيتم انعكاس أي تغيير في القائمة الأصلية في واحد عكس.
import com.google.common.collect.Lists;
[...]
final List<String> myList = Lists.newArrayList("one", "two", "three");
final List<String> myReverseList = Lists.reverse(myList);
System.out.println(myList);
System.out.println(myReverseList);
myList.add("four");
System.out.println(myList);
System.out.println(myReverseList);
تعطي النتيجة التالية:
[one, two, three]
[three, two, one]
[one, two, three, four]
[four, three, two, one]
مما يعني أنه يمكن كتابة التكرار العكسي لحفظه على النحو التالي:
for (final String someString : Lists.reverse(myList) {
//do something
}
يمكنك عكس سطر واحد
مجموعات. عرض (قائمة)؛
ArrayList arrayList = new ArrayList();
arrayList.add("A");
arrayList.add("B");
System.out.println("Before Reverse Order : " + arrayList);
Collections.reverse(arrayList);
System.out.println("After Reverse : " + arrayList);
انتاج |
Before Reverse Order : [A, B]
After Reverse : [B, A]
يمكنك القيام بذلك إذا كنت مرتاحا مع foreach loop.
List<String> list = new ArrayList<String>();
list.add("ABC");
list.add("DEF");
list.add("GHI");
ListIterator<String> listIterator = list.listIterator(list.size());
while(listIterator.hasPrevious()){
System.out.println(listIterator.previous());
}