التكرار العكسي من خلال Arraylist يعطي IndexOutofBoundSexception

StackOverflow https://stackoverflow.com/questions/580269

سؤال

عندما أعرب التكرار فوق قائمة صفيف أحصل على فهرسة حاولت إجراء التكرار إلى الأمام ولا توجد مشكلة. أتوقع وأعلم أن هناك خمسة عناصر في القائمة. الرمز أدناه:

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());
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top