java.util.List 的降序迭代器 [英] descendingIterator for java.util.List
问题描述
LinkedList 可以像这样使用升序或降序迭代器进行迭代:
LinkedList
<块引用>
厌恶:你好 2 巧克力 10逆转:10 巧克力 2 你好
但是 descendingIterator 不适用于 List 和 ArrayList.是否有任何解决方法或在列表说明中,为什么 List 中没有 descendingIterator?
问题类似于可以以相反的顺序对 java 中的每个循环执行一次?.但所有答案都推荐临时解决方案或第 3 方库.
可能有可能使用流吗?(不幸的是,我的谷歌搜索只给出了流Java 8流反向顺序的缺失标准反向)
正如我所提到的,我的问题与关于流的问题有关,但是:
- 使用流只是一种选择,问题是关于java.util.Iterator 和 java.util.List
- 该问题的答案仅解决了部分情况,但显示没有方便的一般反向.如果我没有遗漏术语 List 是有序集合,可比较项的排序,以实现顺序减小范围.
List
没有降序迭代器并没有很好的理由.每个 List
都需要支持一个 ListIterator
,它可以使用 hasPrevious()
和 previous()
以相反的顺序迭代代码>方法.不过,这似乎是一个相当不常见的用例.
这里有一个小实用方法,它使 Iterable
适应以相反顺序迭代的 ListIterator
:
static 可迭代的<T>降序Iterable(列表列表){返回 () ->{列表迭代器li = list.listIterator(list.size());返回新的迭代器(){public boolean hasNext() { return li.hasPrevious();}公共 T next() { return li.previous();}};};}
您可以使用它来实现您的示例:
Listlist = Arrays.asList("你好", "2", "巧克力", "10");StringJoiner sj = new StringJoiner(" ");降序迭代器(列表).迭代器().forEachRemaining(sj::add);System.out.println(sj);10 巧克力 2 你好
或者您可以在增强的 for 循环中使用它:
for (String s :DescingIterable(list)) {System.out.println(s);}10巧克力2你好
我最初让它创建了一个 Iterator
而不是 Iterable
,但后者更有用,因为它可以在增强的 for 循环中使用.
请注意,这里还有一个小问题,即如果 List
可以同时修改,则会出现竞争条件.这发生在此处的代码中:
list.listIterator(list.size())
如果这是可能的,您要么必须对列表使用外部同步,或者如果列表是 CopyOnWriteArrayList
,您必须先克隆它.有关后者的更多信息,请参阅此答案.
LinkedList can be iterated using ascending or descending iterator like this:
LinkedList<Object> list = new LinkedList<Object>();
...
StringJoiner sJ1 = new StringJoiner(" ");
list.iterator().forEachRemaining(a -> sJ1.add(a.toString()));
System.out.println("averse: \n" + sJ1.toString());
StringJoiner sJ2 = new StringJoiner(" ");
list.descendingIterator().forEachRemaining(a -> sJ2.add(a.toString()));
System.out.println("reverse: \n" + sJ2.toString());
averse: Hello 2 Chocolate 10 reverse: 10 Chocolate 2 Hello
But descendingIterator isn't available for List and ArrayList. Are there any workaround or at list explanation, why descendingIterator is absent in List?
Question is similar to Can one do a for each loop in java in reverse order?. But all the answers recommend ad hoc solutions or 3rd party libraries.
May be there is this is possible using streams streams? (Unfortunately my googling gives only absence standard reverse for stream Java 8 stream reverse order)
As I've mentioned my questions is related to that about streams, but:
- Using of stream is only an option, question is about java.util.Iterator and java.util.List
- Answers to that question solved only partial case, but showed absence of convenient general reverse. If I'm not missing the term List is ordered collection, sorting of Comparable items, to achieve order decreases the scope.
There's no really good reason why List
couldn't have a descending iterator. Every List
is required to support a ListIterator
which can be iterated in reverse order using the hasPrevious()
and previous()
methods. This seems to be a fairly uncommon use case, though.
Here's a little utility method that adapts an Iterable
to a ListIterator
iterating in reverse order:
static <T> Iterable<T> descendingIterable(List<? extends T> list) {
return () -> {
ListIterator<? extends T> li = list.listIterator(list.size());
return new Iterator<T>() {
public boolean hasNext() { return li.hasPrevious(); }
public T next() { return li.previous(); }
};
};
}
You could use it to implement your example:
List<String> list = Arrays.asList("Hello", "2", "Chocolate", "10");
StringJoiner sj = new StringJoiner(" ");
descendingIterable(list).iterator().forEachRemaining(sj::add);
System.out.println(sj);
10 Chocolate 2 Hello
Or you could use it in an enhanced-for loop:
for (String s : descendingIterable(list)) {
System.out.println(s);
}
10
Chocolate
2
Hello
I initially had this create an Iterator
instead of an Iterable
, but the latter is more useful since it can be used in an enhanced-for loop.
Note also there is a small wrinkle here which is that there is a race condition if the List
can be concurrently modified. This occurs at the code here:
list.listIterator(list.size())
If this is a possibility, you either have to use external synchronization on the list, or if the list is a CopyOnWriteArrayList
, you have to clone it first. See this answer for further information on the latter.
这篇关于java.util.List 的降序迭代器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!