基於Java8的LINQ開源專案:Java Enumerable

banq發表於2014-03-08
微軟推出的LINQ曾經領先Java很長一段時間,如今隨著Java 8的lambdas推出,Java總算趕上來,streams有如下方法:
map
filter
flatMap
distinct
sorted
limit (i.e. take)
skip
reduce (i.e fold)
min
max
any
all
generate (for building infinite lists)

但是有一問題不能擴充套件它們,比如如果希望實現如下:
first
last
nth
windowed
intersperse
intercalate
tails
intersect
zip
groupRuns

這些都是F#/Haskell的豐富函式功能,.NET 是使用 extension方法解決lambda這個問題的。

如今使用Java 8重新構建的LinQ開源專案推出:Java Enumerable

這個受F#,C#和Haskell的啟發,使用Java遞延懶集合的實現。目標是使與iterable中元素更容易打交道,提供如下:
Map
Zip
Zip3
Filter
FlatMap
Order
OrderBy
OrderDesc
OrderByDesc
Take
TakeWhile
Skip
SkipWhile
Iter
Iteri
DistinctUnion
Distinct
DistinctBy
Intersect
Except
First
Last
Nth
Fold
FoldWithDefaultSeed
Any
All
Windowed
Tails
Pairwise
GroupRuns
Intersperse
Intercalate
ToDictionary
ToGroupedDictionary
Range
Min
Max
MinBy
MaxBy

比如Iterator 鏈實現如下:

private Function<Iterable<TSource>, Iterator<TSource>> iteratorGenerator;
 
public static <TSource> Enumerable<TSource> init(Iterable<TSource> source){
    return new Enumerable<>(_ig -> new EnumerableIterator<>(source));      
}                                                                          
 
protected Enumerable(Function<Iterable<TSource>, Iterator<TSource>> iteratorGenerator) {
    this.iteratorGenerator = iteratorGenerator;                                         
}                                                                                       
 
@Override                               
public Iterator<TSource> iterator() {    
    return iteratorGenerator.apply(this);
}                                        
        
// The underlying iterator
 
public class EnumerableIterator<TSource> implements Iterator<TSource> {
    protected Iterator<TSource> source;
    private Iterable<TSource> input;
 
    public EnumerableIterator(Iterable<TSource> input){
        this.input = input;
 
        reset();
    }
 
    protected void reset(){
        source = input.iterator();
    }
 
    @Override
    public boolean hasNext() {
        return source.hasNext();
    }
 
    @Override
    public TSource next() {
        return (TSource)source.next();
    }
}               
<p class="indent">

基本思想是是為你想要做的每一個型別的處理建立一個迭代器,如果你要做一個map函式,你應當建立一個迭代器iterator來包裹源.

更多案例見:http://onoffswitch.net/building-linq-java/

[該貼被banq於2014-03-08 15:45修改過]

相關文章