【问题标题】:Java Stream to Array after mapping映射后Java Stream to Array
【发布时间】:2017-07-17 11:03:28
【问题描述】:

我有以下代码,它是我偶然发现的东西的简化版本:

public class Transforming
{
    static interface MyInterface<T>
    {
        void consume(T... toConsume);
    }

    static abstract class Mapper<T> implements MyInterface<String> {
        MyInterface<T> delegate;

        public Mapper(MyInterface<T> delegateTo)
        {
            delegate = delegateTo;
        }

        public void consume(String... transformFrom)
        {
            T[] array = (T[]) Arrays.stream(transformFrom)
                    .map(this::transform)
                    .toArray(); // can't toArray(T[]::new) here!
            delegate.consume(array);
        }

        protected abstract T transform(String toTransform);
    }
}

关于如何将流转换为数组的搜索显然不足,因为此时我没有结果类型的数组,而且 Java 不允许我创建泛型类型的数组...

我确实理解这个问题,但是关于如何清理代码的任何意见? AFAICT,我的选择是

  • 将界面从可变参数更改为列表
  • 我在代码示例中使用的演员表
  • 将 IntFunction 添加到 Mapper 创建中

我缺少什么吗? 您的偏好是什么?

【问题讨论】:

  • 你的 Mapper.consume 方法没有实现接口,因为它在参数类型中有 String 而不是 T
  • @talex你当然是对的,我更正了OP以实现MyInterface&lt;String&gt;

标签: java arrays generics java-stream


【解决方案1】:

我处理这个问题的方法是始终提供两个重载:

  • 接受可变参数的一种

  • 接受List&lt;&gt;

可变参数重载除了将数组打包到列表中并调用List&lt;&gt; 重载外,从不做任何事情。这使事情变得简单。不费吹灰之力。

因此,基本上,我选择的选项是您的第一个选项,“将接口从可变参数更改为列表”,除了您实际上不必更改它,您可以通过添加重载来扩展它。

【讨论】:

  • 这实际上是我以前的 :) 我试图摆脱接口中方法的列表版本,因为它没有在任何地方调用。
  • “未在任何地方调用”或“仅从一个地方调用”不是从接口中删除方法的理由。决定一个方法是否属于接口的标准完全取决于接口需要提供的功能,而不是调用者可能(或可能不)做的用途。这里的可选函数是 varargs 函数,它纯粹是为了方便调用者而提供的。基本函数是接受列表的函数。
  • 没错。由于 varargs 方法可以在接口中作为 default 方法提供,因此没有理由考虑删除方法(除非 varargs 方法被证明是无用的)。对于实现者来说,实现的单一方法是consume(T...)还是consume(List&lt;T&gt;)没有区别……
【解决方案2】:

您的抽象Mapper 类可以使用抽象toArray 方法,该方法提供从列表到数组的类型化转换。

static abstract class Mapper<T> implements MyInterface<String> {

    @Override
    public void consume(String... transformFrom) {
        T[] array = toArray(Arrays.stream(transformFrom)
                .map(this::transform)
                .collect(Collectors.toList()));
        delegate.consume(array);
    }

    protected abstract T transform(String toTransform);
    protected abstract T[] toArray(List<T> list);
}

在实现中只需实现一个基本的list.toArray(..) 方法

public static void main(String[] args) {
    Mapper myMap = new Mapper<Integer>(new MapperInt()) {

        @Override
        protected Integer transform(String toTransform) {
            return new Integer(toTransform);
        }

        @Override
        protected Integer[] toArray(List<Integer> list) {               
            return list.toArray(new Integer[list.size()]);
        }

    };
    myMap.consume("1","2");
}

public static class MapperInt implements MyInterface<Integer> {

    @Override
    public void consume(Integer... toConsume) {
        for(Integer i: toConsume)
            System.err.println(i);
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-07
    • 1970-01-01
    • 2021-08-28
    • 2018-11-28
    • 2021-03-01
    • 2018-10-25
    • 1970-01-01
    • 2023-03-25
    相关资源
    最近更新 更多