web-dev-qa-db-ja.com

Javaでリストの逆リストビューを取得する方法

List#sublistがリストのサブリストビューを提供するのと同じ方法で)リストの逆リストビューを持ちたいです。この機能を提供する機能はありますか?

私はリストのコピーを作成したり、リストを変更したりしたくはありません。

ただし、この場合はリストに少なくとも1つのリバースイテレータを取得できれば十分です。


また、私はこれを自分で実装する方法を知っています。私は、Javaがすでにこのようなものを提供しているのかどうかを尋ねています。

デモの実装

static <T> Iterable<T> iterableReverseList(final List<T> l) {
    return new Iterable<T>() {
        public Iterator<T> iterator() {
            return new Iterator<T>() {
                ListIterator<T> listIter = l.listIterator(l.size());                    
                public boolean hasNext() { return listIter.hasPrevious(); }
                public T next() { return listIter.previous(); }
                public void remove() { listIter.remove(); }                 
            };
        }
    };
}

私はちょうどいくつかのListの実装がdescendingIterator()を持っていることを知りました。それが私が必要としているものです。 Listにはそのような一般的な実装はありませんが。私がLinkedListで見た実装はどんなListでも動作するのに十分に一般的であるので、これはちょっと奇妙なことです。

203
Albert

Guava これがこれを提供します: Lists.reverse(List)

List<String> letters = ImmutableList.of("a", "b", "c");
List<String> reverseView = Lists.reverse(letters); 
System.out.println(reverseView); // [c, b, a]

Collections.reverseとは異なり、これは純粋にビューです...これは元のリストの要素の順序を変更しません。さらに、変更可能な元のリストでは、元のリストとビューの両方に対する変更が他方に反映されます。

196
ColinD

リストで.clone()メソッドを使用してください。これは浅いコピーを返します。つまり、同じオブジェクトへのポインタが含まれるため、リストをコピーする必要はありません。それからコレクションを使ってください。

エルゴ、

Collections.reverse(list.clone());

Listを使用していてclone()にアクセスできない場合は、 subList() を使用できます。

List<?> shallowCopy = list.subList(0, list.size());
Collections.reverse(shallowCopy);
202
jcalvert

私が正しいと理解したならば、それは1行のコードです。それは私のために働きました。

 Collections.reverse(yourList);
78
Shakeeb Ayaz

厳密にはエレガントではありませんが、List.listIterator(int index)を使用すると、リストの最後まで双方向のListIteratorを取得できます。

//Assume List<String> foo;
ListIterator li = foo.listIterator(foo.size());

while (li.hasPrevious()) {
   String curr = li.previous()
}
31
kkress

Collections.reverse(nums)...実際には要素の順序を逆にします。以下のコードは大歓迎です -

List<Integer> nums = new ArrayList<Integer>();
nums.add(61);
nums.add(42);
nums.add(83);
nums.add(94);
nums.add(15);
//Tosort the collections uncomment the below line
//Collections.sort(nums); 

Collections.reverse(nums);

System.out.println(nums);

出力:15、94、83、42、61

これは古い記事だと思いますが、今日はこのようなものを探していました。最後に私は自分自身でコードを書いた:

private List reverseList(List myList) {
    List invertedList = new ArrayList();
    for (int i = myList.size() - 1; i >= 0; i--) {
        invertedList.add(myList.get(i));
    }
    return invertedList;
}

長いリストにはお勧めできません。これはまったく最適化されていません。これは制御されたシナリオのための一種の簡単な解決策です(私が扱うリストには10​​0以下の要素があります)。

誰かに役立つことを願っています。

4
CocheLee

Java.util.DequeにはdescendingIterator()があります - あなたのListDequeであれば、それを使うことができます。

4
Bozho

私はこれを使う:

public class ReversedView<E> extends AbstractList<E>{

    public static <E> List<E> of(List<E> list) {
        return new ReversedView<>(list);
    }

    private final List<E> backingList;

    private ReversedView(List<E> backingList){
        this.backingList = backingList;
    }

    @Override
    public E get(int i) {
        return backingList.get(backingList.size()-i-1);
    }

    @Override
    public int size() {
        return backingList.size();
    }

}

このような:

ReversedView.of(backingList) // is a fully-fledged generic (but read-only) list
3
Museful

小さいサイズのリストでは、LinkedListを作成してから、降順の反復子を次のように使用できます。

List<String> stringList = new ArrayList<>(Arrays.asList("One", "Two", "Three"));
stringList.stream().collect(Collectors.toCollection(LinkedList::new))
         .descendingIterator().
         forEachRemaining(System.out::println); // Three, Two, One
System.out.println(stringList); // One, Two, Three
1
i_am_zero

オブジェクトを要求するときに位置を反転することもできます。

Object obj = list.get(list.size() - 1 - position);
1
fede1608

またこれをすることができます:

static ArrayList<String> reverseReturn(ArrayList<String> alist)
{
   if(alist==null || alist.isEmpty())
   { 
       return null;
   }

   ArrayList<String> rlist = new ArrayList<>(alist);

   Collections.reverse(rlist);
   return rlist;
}
1
jhdrosos