【问题标题】:Java 8 Stream of Super Classes, Parent Files, Component Parents, linked list, etcJava 8 Stream of Super Classes、Parent Files、Component Parents、链表等
【发布时间】:2016-04-29 15:26:23
【问题描述】:

我想将以下 for 语句转换为 Java 8 流(即 Stream<Class<?>>)。理想的解决方案应该足够简单,我可以轻松地将其调整为遍历链表的各种情况(例如File.getParentFile()Component.getParent())。

  Class<?> clazz;
  Object value;

  value = ...;

  for (clazz = value.getClass(); clazz != null; clazz = clazz.getSuperclass())
     ...

我意识到创建流的几行代码不会比单个for 语句更简单。然而,流使for 循环的主体更简单,因此流是可取的。

【问题讨论】:

    标签: java java-stream spliterator


    【解决方案1】:

    您需要一个 takeWhile 方法,该方法仅出现在 JDK-9 中。目前,您可以使用可用的后端端口,例如,在我的 StreamEx 库中:

    Stream<Class<?>> stream = StreamEx.iterate(value.getClass(), Class::getSuperClass)
                                      .takeWhile(Objects::nonNull);
    

    在 JDK-9 中,只需将 StreamEx 替换为 Stream

    【讨论】:

    • JDK-9 也允许Stream.iterate(value.getClass(), Objects::nonNull, Class::getSuperclass)
    • JDK-8 可以做一个更简单的 Stream.iterate,没有转义函数。例如递归读取 Throwable 原因:Stream.iterate(ex, Throwable::getCause)
    【解决方案2】:

    这里的代码与问题中的代码相同,但使用Spliterator 实现。我希望有人能想出一个更简单、更聪明的答案。

      Class<?> clazz;
      Object value;
    
      value = ...;
    
      <Class<?>>walkLinks(value.getClass(), Class::getSuperclass).
         ...
    
    
    public static <T> Stream<T> walkLinks(T start, Function<T, T> next)
    {
       WalkLinks<T> walker;
       Stream<T> result;
    
       walker = new WalkLinks<>(start, next);
       result = StreamSupport.stream(walker, false);
    
       return(result);
    }
    
    private static class WalkLinks<T> extends Spliterators.AbstractSpliterator<T>
    {
       private final Function<T, T> m_next;
       private       T              m_value;
    
       public WalkLinks(T value, Function<T, T> next)
       {
          super(Long.MAX_VALUE, Spliterator.ORDERED + Spliterator.NONNULL);
    
          m_value = value;
          m_next  = next;
       }
    
       @Override
       public boolean tryAdvance(Consumer<? super T> action)
       {
          if (m_value == null)
             return(false);
    
          action.accept(m_value);
    
          m_value = m_next.apply(m_value);
    
          return(true);
       }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-13
      • 1970-01-01
      相关资源
      最近更新 更多