2015-12-02 87 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表達式,它看起來並不簡潔