繁体   English   中英

Java 中的自定义迭代器和方法链接

[英]Custom Iterator and method chaining in Java

我的自定义迭代器有问题,所以我请求你的帮助。 我有 class MyIterator,它是一个带有转换的迭代器。 这个 class 有方法:

  • next() - 返回下一个元素
  • hasNext() - 检查下一个元素是否存在
  • fromIterator - static 方法,将 Iterator 转换为 MyIterator
  • map - 采用功能接口并返回 MyIterator 的方法,该方法具有与该接口对应的转换规则
  • forEach - 采用功能接口并根据接口迭代所有剩余对象的方法。

    我的实现是

    import java.util.Iterator;
    import java.util.function.Consumer;
    import java.util.function.Function;

    public class MyIterator<K, V> {
        private final Iterator<K> iterator;
        private final Function<K, V> function;

        @SuppressWarnings("unchecked")
        public static <K, V> MyIterator<K, V> fromIterator(Iterator<K> iterator) {
            return new MyIterator<>(iterator, k -> (V) k);
        }

        private MyIterator(Iterator<K> iterator, Function<K, V> function) {
            this.iterator = iterator;
            this.function = function;
        }

        public V next() {
            return this.function.apply(iterator.next());
        }

        public boolean hasNext() {
            return this.iterator.hasNext();
        }

        public MyIterator<K, V> map(Function<K, V> function) {
            return new MyIterator<K, V>(this.iterator, this.function);
        }

        public void forEach(Consumer<V> action) {
            while (hasNext()) {
                action.accept(this.next());
            }
        }
    }

所以,我做了这个任务,但我不明白,如何将方法map更改为链接方法(管道) 我的意思是:


    MyIterator<String, Integer> myIterator3 = MyIterator.fromIterator(stringsArray.iterator()).map(s -> s.length()).map(i -> i.toString()).map(s -> s.length());

例如,我有字符串“England”。 在第一个 map 之后,我想得到 7(“England”由 7 个字符组成),而不是“7”,而不是 1(因为字符串“7”由 1 个字符组成)。
我的假设是我应该在我的方法 map 中使用方法andThen/compose ,我不明白,怎么做。

更新您的自定义 Iterator 并允许fromIterator() takes function 而不是您定义它


public class MyIterator<K, V> {

    private Iterator<K> iterator;
    private List<Function<K, ?>> functions;

    public static <K, V> MyIterator<K, V> fromIterator(Iterator<K> iterator) {
        return new MyIterator<>(iterator);
    }

    private MyIterator(Iterator<K> iterator) {
        this.iterator = iterator;
        functions = new ArrayList<>();
    }

    private MyIterator(Iterator<K> iterator, Function<K, ?> function) {
        this.iterator = iterator;
        functions = new ArrayList<>();
        functions.add(function);
    }

    private MyIterator(Iterator<K> iterator, List<Function<K, ?>> functions) {
        this.iterator = iterator;
        this.functions = functions;
    }

    public Object next() {
        K key = iterator.next();
        Object val = null;
        for (int i = 0; i < functions.size(); i++) {
            val = functions.get(i).apply(key);
            key = (K) val;
        }
        return val;
    }

    public boolean hasNext() {
        return iterator.hasNext();
    }

    public <R, RR> MyIterator<R, RR> map(Function<K, R> function) {
        List<Function<K, ?>> functions2 = this.functions;
        functions2.add(function);
        return new MyIterator(iterator, functions2);
    }

    public void forEach(Consumer<Object> action) {
        while (hasNext()) {
            action.accept(next());
        }
    }
}

, 主要的


    public static void main(String[] args) throws Exception {
        Iterator<String> sIterator = Arrays.asList("aaa", "bbbb", "cccc", "ddddd").iterator();
        MyIterator.<String, Object>fromIterator(sIterator).map(s -> s.length()).map(i -> i + "")
                .map(str -> str.length()).forEach(System.out::println);
    }

, output

1
1
1
1

由于Iterator接受一个参数,因此这是我修改代码的方式。

public class ChainedIterator<T> {

    private Function<T, ?> action;

    private ChainedIterator<T> chain;

    private final Iterator<?> iterator;

    private <R> ChainedIterator(Iterator<?> iterator, Function<T, R> action, ChainedIterator<T> prev) {
      this.action = action;
      this.chain = prev;
      this.iterator = iterator;
    }

    public static <T> ChainedIterator<T> fromIterator(Iterator<T> iterator) {
      return new ChainedIterator<>(iterator, Function.identity(), null);
    }

    public T next() {
      return (T) this.action.apply((T) (Objects.nonNull(this.chain) ? this.chain.next() : this.iterator.next()));
    }

    public boolean hasNext() {
      return this.iterator.hasNext();
    }

    public <R> ChainedIterator<R> map(Function<T, R> action) {
      return new ChainedIterator(this.iterator, action, this);
    }

    public void forEach(Consumer<T> action) {
      while (hasNext()) {
        action.accept(this.next());
      }
    }
 }

使用示例

Iterator<String> stringIterator = Arrays.asList("England", "India").iterator();

ChainedIterator<Integer> iterator = ChainedIterator.fromIterator(stringIterator)
  .map(s -> s.length())
  .map(i -> String.valueOf(i))
  .map(s -> s.length());

我希望这有帮助:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM