go stream实现二

之前给了基于go的自定义Stream实现,一直觉得比较变扭,和java自定义的实现风格也不太一致,
随着对go语法的进一步理解,参考之前写的java自定义Stream实现逻辑,对go 的Stream实现进行了优化

步骤一:函数定义

通过go 的type关键字对Stream相关函数进行定义,方便后续使用

//定义Consumer函数类型
type Consumer[T any] func(t T)

//定义Predicate函数类型
type Predicate[T any] func(t T) bool

//定义Convert行数类型(对应java的Function)
type Convert[T any] func(t T) T

//定义Stream函数类型
type Stream[T any] func(c Consumer[T])

对于type Stream[T any] func(c Consumer[T]) ,和java实现方式中的Pipeline接口等价,是一切的开始

步骤二:提供Stream初始化方法

func OfStream[T any](arr []T) Stream[T] {
	var stream Stream[T] = func(c Consumer[T]) {
		for _, v := range arr {
			c(v)
		}
	}
	return stream
}

这里是示例基于arr []T产生Stream,你也可以基于自己的诉求来构建这个Stream,例如可以实现从文件中读数据参数流,从数据库中读数据参数流,从网络中读数据参数流等等

步骤三:提供通用的Map函数

func (s Stream[T]) Map(cv Convert[T]) Stream[T] {
	var stream Stream[T] = func(c Consumer[T]) {
		s(func(t T) {
			c(cv(t))
		})
	}
	return stream
}

代码实现上,重新构建了一个Stream函数,新的Stream函数的实现上,会调用原来的Stream函数,原来的函数需要一个Consumer函数参数,(func(t T) {c(cv(t))},就是Consumer的实例,逻辑上就是把数据map后再给到新Stream的Consumer函数进行消费

步骤四:提供Filter函数

func (s Stream[T]) Filter(test Predicate[T]) Stream[T] {
	var stream Stream[T] = func(c Consumer[T]) {
		s(func(t T) {
			if test(t) {
				c(t)
			}
		})
	}
	return stream
}

理解了Map函数的逻辑后,Filter的逻辑应该就比较好理解,就是过滤符合条件的数据给新Stream函数的Consumer消费

步骤五:提供Reduce函数

func (s Stream[T]) ToSlice() []T {
	result := make([]T, 0)
	s(func(t T) {
		result = append(result, t)
	}
	return result
}

以上是一个reduce函数实现示例,将结果放到Slice中

测试

package main

import (
	"fmt"
	"gotest/main/algorithm"
)

func main() {

	stream := algorithm.OfStream[int]([]int{1, 2, 3, 4, 5, 6})
	r := stream.
		Map(func(t int) int { return t + 1 }).        //2,3,4,5,6,7
		Map(func(t int) int { return t * 3 }).        //6,9,12,,15,18,21
		Filter(func(t int) bool { return t%2 == 0 }). //6,12,18
		ToSlice()
	fmt.Println(r)
}
//输出结果:[6 12 18]

总结

通过上面的实现,就和java的实现方式很接近了,只要掌握了原理,不同语言的实现主要是语法上的差异,逻辑上应该是一致的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值