用go語言實作類別似java8的Stream

來源:互聯網
上載者:User

標籤:merge   func   java8   return   排序   rate   ret   span   格式化   

JDK8 Stream 是一個支援泛型和函數式資料流,使用起來非常強大方便。最近在學習 go 語言我就用 go 模仿了一下類似的功能,
由於 go 對泛型、函數式的支援比較有限,感覺泛型和函數式這一塊實現起來有些彆扭,可能是我不會用,不當之處請高手指點。

Stream 具備部分與整體一致的結構設計,可很方便用來實現各種遞迴演算法,尾部有一個Nil作為遞迴跳出點。
“左摺疊”和“右摺疊” 是非常強大的操作,大多數其它操作都可以通過摺疊實現的,
Stream 自身的很多方法也是通過摺疊操作實現的,如反向、合并、篩選、排序等。
Stream 的參數類型為空白介面,支援泛型型別。
Stream 提供的很多方法都是接受函數作為參數的 “高階方法”,比如:filter ,map ,reduce

Stream 支援用數學歸納法產生各種數列,步驟非常簡單:
1、給出一個遞迴結束的值. 例如: f(1) =1
2、指定 f(n-1).
3、用f(n-1)定義f(n). 例如:f(n)= f(n-1) + 1

goStream 的原始碼如下
package stream import (    "fmt"    "strings") //泛型型別定義type T interface{}type U interface{} //StreamCompute資料結構定義type Stream struct {    Head     T    Tail     *Stream    Length   int    NotEmpty bool} var Nil = Stream{} func Generate(r Stream, f func(Stream) T, m int) Stream {     if m == 1 {        return r    } else {        return Generate(New(f(r), &r), f, m-1)    }} func New(head T, tail *Stream) Stream {    return Stream{head, tail, tail.Length + 1, true}} func (s Stream) Add(i T) Stream {    return New(i, &s)} func (s Stream) Addall(i ...T) Stream {    for _, v := range i {        s = s.Add(v)    }    return s} //左摺疊 用於實現 reduce 的功能func (s Stream) FoldLeft(i U, f func(U, T) U) U {    if s.NotEmpty {        return s.Tail.FoldLeft(f(i, s.Head), f)    } else {        return i    }} //右摺疊func (s Stream) FoldRight(i U, f func(U, T) U) U {    if s.NotEmpty {        return f(s.Tail.FoldRight(i, f), s.Head)    } else {        return i    }} //合并兩個 Streamfunc (s Stream) Merge(t Stream) Stream {    if t.NotEmpty {        return t.FoldRight(s, func(u U, t T) U {            return u.(Stream).Add(t)        }).(Stream)     } else {        return s    }} //倒序func (s Stream) Reverse() Stream {    return s.FoldLeft(Nil, func(u U, t T) U {        return u.(Stream).Add(t)    }).(Stream)} //Mapfunc (s Stream) Map(f func(T) U) Stream {    return s.FoldRight(Nil, func(u U, t T) U {        return u.(Stream).Add(f(t))    }).(Stream)} //Reducefunc (s Stream) Reduce(i T, f func(T, T) T) T {    if s.NotEmpty {        return s.Tail.Reduce(f(i, s.Head), f)    } else {        return i    }} //過濾func (s Stream) Filter(f func(T) bool) Stream {    return s.FoldRight(Nil, func(u U, t T) U {        if f(t) {            return u.(Stream).Add(t)        } else {            return u        }    }).(Stream)} //歸併排序func (s Stream) Sort(c func(T,T) bool) Stream {n := s.Length / 2if n == 0 {return s}else{x,y := split(s, Nil, n)return merge(x.Sort(c),y.Sort(c),c)}}func split(x,y Stream , n int) (Stream,Stream) {if (n == 0 || !x.NotEmpty) {return x,y}return split(*x.Tail, y.Add(x.Head), n - 1);} func merge(x,y Stream , c func(T,T) bool) Stream {if (!x.NotEmpty){        return y;}if (!y.NotEmpty){return x;}if c(x.Head,y.Head) {return merge(*x.Tail, y, c).Add(x.Head)}else{return merge(x, *y.Tail, c).Add(y.Head);}}//格式化顯示 Stream 的所有項func (s Stream) ToString() string {    return "{" + strings.Join(s.FoldRight([]string{}, func(u U, t T) U {        return append(u.([]string), fmt.Sprintf("%v", t))    }).([]string), ",") + "}"}
使用的範例
package main import (    "fmt". "./stream""strings") func main() {x := Generate(Nil.Add(1),func(s Stream) T {return s.Head.(int)+1},50) // {1,2,3,...,48,49,50}x = x.Map(func(t T) U {        p := t.(int) //平方映射        return p * p    }).Filter(func(t T) bool {        return t.(int) % 2 == 0 //偶數過濾    })//計算所有項的和fmt.Printf("sum %s = %d\n",x.ToString(),x.FoldLeft(0,func(u U, t T) U {return u.(int) + t.(int)})) //22100//浮點數列表求和y := Nil.Addall(3.5, 4.3, 2.6, 1.1, 7.83, 4.42)    fmt.Printf("%.2f\n", y.Reduce(0.0, func(t T, t2 T) T {        return t.(float64) + t2.(float64)    }))//排序z := Nil.Addall(4,3,7,6,2,1,9,5,8,0).Sort(func(x,y T) bool {return x.(int) > y.(int)})fmt.Println(z.ToString()) //{0,1,2,3,4,5,6,7,8,9}//列出包含a字元的字串    g := Nil.Addall("aaa", "bbb", "aba", "ccc", "cbb", "cba")    fmt.Println(g.Filter(func(t T) bool {        return strings.Contains(t.(string), "a")    }).ToString())     //產生斐波拉契亞數列 的前 20 項    fmt.Println(Generate(Nil.Addall(1, 1), func(s Stream) T {        return s.Head.(int) + s.Tail.Head.(int)    }, 19).ToString())      //通過數列 π = 2 + 2/3 + 2/3*2/5 + 2/3*2/5*3/7  + ... + f(n-1) * n/(2*n+1) 計算圓周率的值    fmt.Println(Generate(Nil.Add(2.0), func(s Stream) T {        n := s.Length        return s.Head.(float64) * float64(n) / (float64(n)*2 + 1)    }, 51).Reduce(0.0, func(t T, t2 T) T {        return t.(float64) + t2.(float64)    }))}

用go語言實作類別似java8的Stream

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.