如何在 Java 中获得列表的反向列表视图?
我想在列表上有一个反向列表视图(与 List#sublist
在列表上提供子列表视图类似)。是否有一些函数可以提供此功能?
我不想复制该列表,也不想修改该列表。
在这种情况下,如果我能在列表上至少获得一个反向迭代器就足够了。
另外,我知道如何自己实现这一点。我只是想问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
一起使用。
I want to have a reversed list view on a list (in a similar way than List#sublist
provides a sublist view on a list). Is there some function which provides this functionality?
I don't want to make any sort of copy of the list nor modify the list.
It would be enough if I could get at least a reverse iterator on a list in this case though.
Also, I know how to implement this myself. I'm just asking if Java already provides something like this.
Demo implementation:
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(); }
};
}
};
}
I just have found out that some List
implementations have descendingIterator()
which is what I need. Though there is no general such implementation for List
. Which is kind of strange because the implementation I have seen in LinkedList
is general enough to work with any List
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
更新 2024.06.16:
在 Emmanuel Bourg 发表精彩评论后,我又看了一眼查看代码并将其升级为现代风格的
null
安全,并纳入了他的出色建议。原始代码位于最后一条水平线下方。它与最新版本的 Java 更加一致,即,利用
null
是一个类型漏洞,改变方法参数是一个类型漏洞代码味道,并且可变性被限制在一个很小的块内。尽可能在单个方法中编写代码,以提高 FP 可组合性(而不是较弱且容易出错的 OOP 可重用性)。对于使用 Java 21 或更高版本的任何人,请使用 List.reversed()。
对于使用 Java 8 到 Java 20 的任何人...
null
List
(强烈的代码味道)List
Stream
的函数流畅的调用风格Collections.reverse()
(已存在于 Java Collections API 中)...这是我生成的一个有用的解决方案:
最初发布的代码 已在上面更新(请勿使用):
UPDATE 2024.06.16:
After an awesome comment from Emmanuel Bourg, I took another look at the code and upgraded it to be modern-style
null
safe, and incorporating his excellent suggestion. The original code is captured below the last horizontal rule.It's considerably more aligned with the latest versions of Java, i.e., exploiting
null
is a type-hole, mutating a method parameter is a type-hole code smell, and mutability being restricted to as small a block of code within a single method as possible to improve FP composability (as opposed to the weaker and error-prone OOP reusability).For anyone on Java 21 or later, use List.reversed().
For anyone on Java 8 through Java 20 who...
null
List<T>
(a strong code smell)List<T>
Stream<T>
's fluent calling styleCollections.reverse()
, already present in the Java Collections API)...here's a useful solution I've generated:
Originally Posted Code that was updated above (DO NOT USE):
您还可以这样做:
You can also do this:
在列表上使用 .clone() 方法。它将返回一个浅表副本,这意味着它将包含指向相同对象的指针,因此您不必复制列表。然后只需使用集合即可。
因此,
如果您使用的是
List
并且无权访问clone()
您可以使用subList()
:Use the .clone() method on your List. It will return a shallow copy, meaning that it will contain pointers to the same objects, so you won't have to copy the list. Then just use Collections.
Ergo,
If you are using a
List
and don't have access toclone()
you can usesubList()
:Guava 提供了以下内容:Lists.reverse(List)
与
集合不同。相反,这纯粹是一个视图...它不会改变原始列表中元素的顺序。此外,对于可修改的原始列表,对原始列表和视图的更改都会反映在另一个列表中。
Guava provides this: Lists.reverse(List)
Unlike
Collections.reverse
, this is purely a view... it doesn't alter the ordering of elements in the original list. Additionally, with an original list that is modifiable, changes to both the original list and the view are reflected in the other.如果我理解正确,那么它就是一行代码。它对我有用。
If i have understood correct then it is one line of code .It worked for me .
它并不完全优雅,但如果你使用 List.listIterator(int index) ,你可以得到一个到列表末尾的双向 ListIterator :
Its not exactly elegant, but if you use List.listIterator(int index) you can get a bi-directional ListIterator to the end of the list:
我用这个:
像这样:
I use this:
like this:
从 Java 21 开始,出现了一个新接口
SequencedCollection
(它是 <代码>列表)。它具有方法reversed()
提供集合的逆序视图:Since Java 21 there is a new interface
SequencedCollection
(which is a superinteface forList
). It has the methodreversed()
which provides a reverse-ordered view of a collection:java.util.Deque
有descendingIterator()
- 如果您的List
是Deque
,您可以使用它。java.util.Deque
hasdescendingIterator()
- if yourList
is aDeque
, you can use that.Collections.reverse(nums) ...它实际上颠倒了元素的顺序。
下面的代码应该非常感激 -
输出:15,94,83,42,61
Collections.reverse(nums) ... It actually reverse the order of the elements.
Below code should be much appreciated -
Output: 15,94,83,42,61
我知道这是一篇旧文章,但今天我正在寻找类似的内容。最后我自己写了代码:
不推荐长列表,这根本没有优化。对于受控场景来说,这是一种简单的解决方案(我处理的列表不超过 100 个元素)。
希望它对某人有帮助。
I know this is an old post but today I was looking for something like this. In the end I wrote the code myself:
Not recommended for long Lists, this is not optimized at all. It's kind of an easy solution for controlled scenarios (the Lists I handle have no more than 100 elements).
Hope it helps somebody.
由于 Java 21 使用
List.reversed
。所以你对原始列表有一个相反的看法。
Since Java 21 use
List.reversed
.So you have a reversed view of the original list.
您还可以在请求对象时反转位置:
You can also invert the position when you request an object:
对于小型列表,我们可以创建 LinkedList,然后可以使用降序迭代器,如下所示:
For small sized list we can create
LinkedList
and then can make use of descending iterator as: