【问题标题】:Java: Get element before or after a given one in an IterableJava:在Iterable中获取给定元素之前或之后的元素
【发布时间】:2013-12-06 11:42:37
【问题描述】:

在给定其中一个元素的情况下,是否有一种非冗长的方式(例如,使用现有库中的方法调用,无论是番石榴还是类似的)从 Iterable 中检索前一个和后一个元素?

我想要一个适合 Iterable 的通用解决方案(如果足够酷,也可以是 Collection),所以请不要发布仅适用于 Set 或 List 等的解决方案(也许添加评论:))。

我需要一个或另一个,我不想在一种方法中找到前一个元素和后一个元素。

我的解决方案如下。如果您想评论返回 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)));
}

【问题讨论】:

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

标签: java collections iterator


【解决方案1】:

在这种情况下,返回 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;
}

【讨论】:

    【解决方案2】:

    我会这样做:

    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;
    }
    

    这应该保存before之前的元素和after之后的元素。

    【讨论】:

      猜你喜欢
      • 2021-11-04
      • 2020-01-22
      • 2015-08-22
      • 1970-01-01
      • 1970-01-01
      • 2011-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多