Java:在Iterable中的给定元素之前或之后获取元素

Java:在Iterable中的给定元素之前或之后获取元素,java,collections,iterator,Java,Collections,Iterator,是否有一种非详细的方法(例如使用现有库中的方法调用,无论是guava还是类似的方法)从Iterable中检索上一个和下一个元素(给定其元素之一) 我想有一个通用的解决方案,适合Iterable(或收集,如果它足够酷),所以请不要张贴解决方案,工作只是为集合或列表等(可能添加一个评论:)) 我需要一个或另一个,我不想在一个方法中同时找到前面和后面的元素 我的解决方案如下。如果您想评论返回null而不是抛出IllegalArgumentException或类似内容,请随时这样做。getElement

是否有一种非详细的方法(例如使用现有库中的方法调用,无论是guava还是类似的方法)从Iterable中检索上一个和下一个元素(给定其元素之一)

我想有一个通用的解决方案,适合Iterable(或收集,如果它足够酷),所以请不要张贴解决方案,工作只是为集合或列表等(可能添加一个评论:))

我需要一个或另一个,我不想在一个方法中同时找到前面和后面的元素

我的解决方案如下。如果您想评论返回null而不是抛出IllegalArgumentException或类似内容,请随时这样做。getElementBefore()方法创建了一个新列表,我对此也不太满意

public static <C> C getElementAfter(final C element, final Iterable<C> iterable) {
    Iterator<C> iterator = iterable.iterator();
    while (iterator.hasNext()) {
        if (iterator.next().equals(element)) {
            if (iterator.hasNext()) {
                return iterator.next();
            } else {
                return null;
            }
        }
    }
    throw new IllegalArgumentException("Iterable does not contain element.");
}

public static <C> C getElementBefore(final C element, final Iterable<C> iterable) {
    return getElementAfter(element, Lists.reverse(Lists.newArrayList(iterable)));
}
publicstaticgetelementafter(finalc元素,finaliterable){
迭代器迭代器=iterable.Iterator();
while(iterator.hasNext()){
if(iterator.next().equals(element)){
if(iterator.hasNext()){
返回iterator.next();
}否则{
返回null;
}
}
}
抛出新的IllegalArgumentException(“Iterable不包含元素”);
}
公共静态C getElementBefore(最终C元素,最终Iterable){
返回getElementAfter(元素,Lists.reverse(Lists.newArrayList(iterable));
}

我会这样做:

Iterator<C> iterator = iterable.iterator();
C before = null;
C after = null;
while (iterator.hasNext()) {
    C current = iterator.next();
    if (current.equals(element)) {
        if (iterator.hasNext()) {
            after = iterator.next();
        }
        break;
    }
    before = current;
}
Iterator Iterator=iterable.Iterator();
C before=null;
C after=null;
while(iterator.hasNext()){
C current=iterator.next();
if(当前等于(元素)){
if(iterator.hasNext()){
after=iterator.next();
}
打破
}
前=电流;
}

在这种情况下,返回null可能更有意义,因为它可能不是例外

可以改进您的getElementBefore实现:

public static <C> C getElementBefore(final C element, final Iterable<C> iterable) {
    C previous = null;
    while (iterator.hasNext()) {
        C current = iterator.next();
        if (current.equals(element)) {
            return previous;
        } else {
            previous = current;
        }
    }

    return null;
}
publicstaticgetelementbefore(finalc元素,finaliterable){
C previous=null;
while(iterator.hasNext()){
C current=iterator.next();
if(当前等于(元素)){
返回上一个;
}否则{
先前=当前;
}
}
返回null;
}

为什么不从
getElementBefore()
调用
getElementAfter()
?不需要复制所有这些代码。@Keppil是的,你是对的,我修复了它,谢谢。我不太喜欢创建一个新列表的开销,但到目前为止,我还没有找到更好的方法。从Iterable中检索上一个和下一个元素的更简单的方法?我没见过。原因可能是
Iterable
是一种错误的“集合”类型。
List
提供了基于索引的直接访问(
List.get(List.indexOf(element)+1)
),您很可能会使用它而不是iterable。@zapl我在处理集合时遇到了这个问题。您可能需要使用Set,因为它提供了其他功能,如惟一性或排序,而这些功能不是列表内置的。例如,番石榴的Iterables.get(iterable,position)使列表的一个功能可供所有Iterables使用。不过,您的实现更加高效,因为您不需要迭代两次来查找元素,然后再查找之前/之后的元素。如果你碰巧使用了a,你可能会使用
higher
lower