Thủ thuật ở đây là định nghĩa "đảo ngược". Người ta có thể sửa đổi danh sách tại chỗ, tạo một bản sao theo thứ tự ngược lại hoặc tạo một chế độ xem theo thứ tự đảo ngược.
Cách đơn giản nhất, nói một cách trực giác , là Collections.reverse
:
Collections.reverse(myList);
Phương pháp này sửa đổi danh sách tại chỗ . Đó là, Collections.reverse
lấy danh sách và ghi đè các yếu tố của nó, không để lại bản sao nào không bị đảo ngược. Điều này phù hợp với một số trường hợp sử dụng, nhưng không phải cho các trường hợp khác; hơn nữa, nó giả sử danh sách có thể sửa đổi. Nếu điều này được chấp nhận, chúng tôi tốt.
Nếu không, người ta có thể tạo một bản sao theo thứ tự ngược lại :
static <T> List<T> reverse(final List<T> list) {
final List<T> result = new ArrayList<>(list);
Collections.reverse(result);
return result;
}
Cách tiếp cận này hoạt động, nhưng yêu cầu lặp lại danh sách hai lần. Trình xây dựng sao chép ( new ArrayList<>(list)
) lặp qua danh sách, và cũng vậy Collections.reverse
. Chúng ta có thể viết lại phương thức này để lặp lại chỉ một lần, nếu chúng ta quá nghiêng:
static <T> List<T> reverse(final List<T> list) {
final int size = list.size();
final int last = size - 1;
// create a new list, with exactly enough initial capacity to hold the (reversed) list
final List<T> result = new ArrayList<>(size);
// iterate through the list in reverse order and append to the result
for (int i = last; i >= 0; --i) {
final T element = list.get(i);
result.add(element);
}
// result now holds a reversed copy of the original list
return result;
}
Điều này là hiệu quả hơn, nhưng cũng dài dòng hơn.
Ngoài ra, chúng tôi có thể viết lại phần trên để sử dụng stream
API của Java 8 , một số người thấy ngắn gọn và dễ đọc hơn phần trên:
static <T> List<T> reverse(final List<T> list) {
final int last = list.size() - 1;
return IntStream.rangeClosed(0, last) // a stream of all valid indexes into the list
.map(i -> (last - i)) // reverse order
.mapToObj(list::get) // map each index to a list element
.collect(Collectors.toList()); // wrap them up in a list
}
nb. điều đó Collectors.toList()
làm cho rất ít đảm bảo về danh sách kết quả. Nếu bạn muốn đảm bảo kết quả trở lại dưới dạng ArrayList, hãy sử dụng Collectors.toCollection(ArrayList::new)
thay thế.
Tùy chọn thứ ba là tạo một khung nhìn theo thứ tự đảo ngược . Đây là một giải pháp phức tạp hơn và đáng để đọc thêm / câu hỏi của riêng nó. Danh sách # phương pháp đảo ngược của ổi là điểm khởi đầu khả thi.
Chọn một cách thực hiện "đơn giản nhất" là một bài tập cho người đọc.