映射

时间:2017-07-17 11:03:29

标签: java arrays generics java-stream

我有以下代码,这是我偶然发现的一个简化版本:

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,我的选择是

  • 将界面从varargs更改为List
  • 我在代码示例中使用的演员
  • 向Mapper创建添加IntFunction

我缺少什么? 你最喜欢什么?

2 个答案:

答案 0 :(得分:5)

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

  • 接受varargs

  • 的人
  • 接受List<>

  • 的人

除了将数组打包到列表中并调用List<>重载之外,varargs重载永远不会做任何事情。这使事情变得简单。是显而易见的。

所以,基本上,我选择的选项是你的第一个选项,“将界面从varargs更改为List”,除了你实际上不需要改变它,你可以通过添加一个重载来扩展它。 / p>

答案 1 :(得分:0)

您的抽象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);
    }

}