2015-12-02 58 views
9

在Haskell映射有一个叫做map函数,该函数A类型的列表和一个函数fA类型的映射值B类型的值。它返回一个类型为B的列表,使得结果列表的每个元素都从f的调用开始,到输入列表中的一个值。等价于(从Haskell的)在Java 7中

例如,给定

  • 列表m = ['a', 'b', 'c']
  • 和功能f = {'a' -> 1, 'b' -> 2, 'c' -> 3}
  • 然后map(m, f) = [1, 2, 3]

是否有一个库,可用于Java 7,提供类似map函数?我已经查看了apache CollectionUtils,发现了forAllDotransform之类的东西,但它们不允许重新调整完全不同类型的集合。谷歌搜索其他图书馆失败的原因相同。

要清楚:我知道如何自己解决问题,但我强烈地感觉到必须已经有一个更好的库来执行这个任务。

奖金问题:是否有一些等同于Java 7中可用的Haskell函子(即从集合到迭代器)?进一步说明:是否有地图功能需要Iterable<A>而不是Collection<A>,并返回Iterable<B>而不是Collection<B>(由拟合函数f提供)?

+0

这听起来就像你真正想要Java 8一样。Java 7不再受到公众的支持。 –

+0

我有我的项目中使用Java 7的限制。 – user3389669

+0

实际上Java 7中没有任何与Haskell等价的函数。 Java中有一个java.util.Map,用于处理键和值。用同样的方法,你可以使用一个对象的值,等等...... –

回答

11

您所要求的Java 7中(与Java 8更容易):

你可以使用Guava并有专门FluentIterable

final List<String> strings = Arrays.asList("a", "b", "c"); 
    final List<Integer> integers = FluentIterable 
      .from(strings) 
      .transform(new Function<String, Integer>() { 
       @Nullable 
       @Override 
       public Integer apply(@Nullable String input) { 
        return input.equals("a") ? 1 : input.equals("b") ? 2 : input.equals("c") ? 3 : -1; 
       } 
      }) 
      .toList(); 

奖金的问题:集合是一个可迭代:-)

+0

这是......实际上比foreach循环流畅得多。 – immibis

1

我不知道这样的库,但什么是错用普通的Java,如:

List<String> m; 
Map<Key,String> map = new HashMap<Key,String>(); 
int c=1; 
for (String i : m) map.put(i,c++); 
2

您需要使用从Java 8流程API使用Java 7中使用流程API官方API不要去碰,但使用:

  1. retrolambda
  2. totallylazy
  3. gradle-retrolambda,或
  4. Lightweight-Stream-API

你可以。更多信息请参阅this post和文档retrolambda,totallylazy,gradle-retrolambda或Lightweight-Stream-API。但是,如果您可以使用Java 8,那么比使用非官方API更容易。

或者可以使用

  • FunctionalExplained Guava
  • Functional Java lib
  • 使用功能编程在Java 7中,但是流API的详细官方和一般。

    2

    你可以自己写一个Iterator,它需要一个map对象进行转换。

    static class Transformer<F, T> implements Iterator<T> { 
    
        final Iterator<F> source; 
        final Map<F, T> map; 
    
        public Transformer(Iterator<F> source, Map<F, T> map) { 
         this.source = source; 
         this.map = map; 
        } 
    
        @Override 
        public boolean hasNext() { 
         return source.hasNext(); 
        } 
    
        @Override 
        public T next() { 
         return map.map(source.next()); 
        } 
    
        public interface Map<F, T> { 
    
         public T map(F f); 
        } 
    } 
    
    private static final String[] numbers = {"Zero", "One", "Two", "Three", "Four", "Five"}; 
    
    public void test() { 
        List<Integer> ints = Arrays.asList(1, 2, 3, 4, 5); 
        Transformer t = new Transformer<>(ints.iterator(), new Transformer.Map<Integer, String>() { 
         @Override 
         public String map(Integer f) { 
          return numbers[f]; 
         } 
    
        }); 
        while (t.hasNext()) { 
         System.out.println(t.next()); 
        } 
    } 
    
    4

    功能变换加入到Java 8和它们不是可用于Java 7。例如,是一种把字符串到整数的映射函数看起来像这样的Java 8

    List<String> list = Arrays.asList("1","2","3"); 
    List<Integer> nums = list.stream().map(Integer::parseInt).collect(Collectors.toList()); 
    

    不像Haskell的,Java集合是严格的,但是Streams(Java 8)是lifted(〜lazy)。

    对于Java 7,有些库支持higher order functions,如Guava。番石榴具有transform功能转换笔 - > U,为前:

    Collection<Integer> ints = Collections2.transform(list, new Function<String, Integer>() { 
         @Override 
         public Integer apply(String s) { 
          return Integer.parseInt(s); 
         } 
        }); 
    

    但是,正如你所知道的,由于缺乏在Java 7中lambda表达式,它看起来并不简洁