当前位置: 首页 > 知识库问答 >
问题:

跳过流< T >中的最后x个元素

闾丘树
2023-03-14

如果我有一个<代码>流

最明显的解决方案是使用<code>limit(originalLength-elementsToRemoveAtEnd),但这需要事先知道初始长度,这并不总是如此。

有没有一种方法可以删除长度未知的流的最后几个元素,而无需将其收集到Collection中,计算元素并再次流式传输?

共有2个答案

澹台奇略
2023-03-14

下面的代码使用<code>ArrayDeque。这会导致第一个<code>n<code>元素被添加到<code>数组</code>中。然后,一旦<code>n

ArrayDeque 不允许元素。下面的代码在添加到 ArrayDeque 之前将 null 映射到NULL_VALUE,然后在从 ArrayDeque 弹出后NULL_VALUE映射回 null

private static final Object NULL_VALUE = new Object();

public static <T> Stream<T> skipLast(Stream<T> input, int n)                   
{
   ArrayDeque<T> queue;

   if (n <= 0)
      return(input);

   queue = new ArrayDeque<>(n + 1);

   input = input.
      map(item -> item != null ? item : NULL_VALUE).
      peek(queue::add).
      skip(n).
      map(item -> queue.pop()).
      map(item -> item != NULL_VALUE ? item : null);

   return(input);
}
薛华奥
2023-03-14

对于长度未知的< code >流,没有通用的无存储解决方案。但是,您不需要收集整个流,您只需要一个与您想要跳过的元素数量一样大的存储空间:

static <T> Stream<T> skipLastElements(Stream<T> s, int count) {
    if(count<=0) {
      if(count==0) return s;
      throw new IllegalArgumentException(count+" < 0");
    }
    ArrayDeque<T> pending=new ArrayDeque<T>(count+1);
    Spliterator<T> src=s.spliterator();
    return StreamSupport.stream(new Spliterator<T>() {
        public boolean tryAdvance(Consumer<? super T> action) {
            while(pending.size()<=count && src.tryAdvance(pending::add));
            if(pending.size()>count) {
              action.accept(pending.remove());
              return true;
            }
          return false;
        }
        public Spliterator<T> trySplit() {
            return null;
        }
        public long estimateSize() {
            return src.estimateSize()-count;
        }
        public int characteristics() {
            return src.characteristics();
        }
    }, false);
}
public static void main(String[] args) {
    skipLastElements(Stream.of("foo", "bar", "baz", "hello", "world"), 2)
    .forEach(System.out::println);
}
 类似资料:
  • 问题内容: 码: 输出: 剩余10秒剩余 8秒剩余 6秒剩余 4秒剩余 完成! 问题: 如何显示“ 剩余2秒 ”?经过的时间确实是10秒,但是最后一个onTick()永远不会发生。如果我将第二个参数从2000更改为1000,则输出为: 剩余10秒剩余 9秒剩余 8秒剩余 7秒剩余 6秒剩余 5秒剩余 4秒剩余 3秒剩余 2秒剩余 完成! 如此看来,似乎跳过了最后一个onTick()调用。顺便说一句

  • 问题内容: 我想知道是否有替代 使用 流 ? 问题答案: 定制收集器可以这样写: 并像这样使用它:

  • 我一直在尝试将更多的函数式编程融入到我所做的事情中,因为我编写的代码具有无副作用的性质,并且在并发代码中具有实用性。我遇到了需要过滤掉java流的连续元素的情况,并且没有比简单的旧命令方法更好的函数方法了。假设我有一个记录参数的程序,我想过滤掉两个连续的元素。例如,。我在日志中想要的是。 我提出了几种方法,但没有一种方法比使用for循环更容易理解,该循环索引了我需要过滤掉的内容。 这似乎是一件很平

  • 我尝试根据过滤最后一个元素的过滤器引发异常: 这样我就可以分辨出为什么在人流中没有发现任何人。是因为年龄还是因为没有人养宠物。 我只看到一个选项,并用两个流来实现它? 或者我能做些什么来把所有的事情都集中在一个流里?

  • 问题内容: 流没有方法: 获取最后一个元素(或对于空Stream为null)的最优雅和/或最有效的方法是什么? 问题答案: 做一个简单地返回当前值的归约:

  • Stream没有方法: 获取最后一个元素(或空流为null)的最优雅和/或最有效的方法是什么?