SoFunction
Updated on 2025-03-05

An example study on how GO simulates streaming operation implementation

Preface

This article is mainly about making a record, I hope it will be useful to you

First of all, you may have seen similar JAVA codes as follows:

return (list).flatMap(list -> ()
                .filter(Objects::nonNull)
                .filter(i -> (()))
                .map(this::mathod)
                .findFirst())
.orElse(null);

With limited time, we try to simulate some methods today and feel it.

gather

First we need a collection as follows:

var okgoarch = List{
    "arm",
    "arm64",
    "loong64",
    "mips64",
    "mips64le",
    "ppc64",
    "riscv64",
    "sparc64",
}

Filtering method

Next we need to try to write a filtering method. This method should accept a method, and the type that needs to be accepted by this method should be a generic type, the return value is BOOL, and then we operate on each element of the set, so the rough look is:

func (ls List) Filter(fk Predicate[string]) List {
  if fk == nil {
    return nil
  }
  var res List
  for _, nod := range ls {
    if fk(nod) {
      res = append(res, nod)
    }
  }
  return res
}
type Predicate[P any] func(n P) bool

Maybe some careful friends have discovered itList I defined this class myself, what if it was another type? Read down

type List []string

Define an interface to handle common types

LIST is actually similar to what I define. For the sake of convenience, there is a question here. If I define other types, it will not work. So we need to define an interface to handle the general types, so the interface comes out:

type Stream[T any] interface {
  Filter(pre Predicate[T]) bool
}

But there is another problem. What should I do if the method implemented by other types may return not BOOL? Then the interface will grow like this. Although it is unlikely that I am still willing to do this in order to achieve the expansion, as follows:

type Stream[T,  OUT any] interface {
  Filter(pre Predicate[T]) OUT
}

Test the logic of filtering string slices

Here, a simple logic of filtering string slices is completed. Let's test it:

 var okgoarch = List{
    "arm",
    "arm64",
    "loong64",
    "mips64",
    "mips64le",
    "ppc64",
    "riscv64",
    "sparc64",
  }
  lss := okgoarch.
    Filter(func(n string) bool { return n == "sparc64" || n == "mips64le" })
  ("%+v\n", lss)
//[mips64le sparc64]

It seems to be quite successful, so I will try to implement a slightly more complicated method.

(()->{}) and other operations

Define a method structure

it is knownMAPThe flow operation method needs to accept a method type as an entry parameter. GO functional programming solves this problem well. First, we need to define a method structure, which is roughly like this:

type Function[F any, OUT any] func(n F) OUT

Define the method hereInput and outgoing ginsengThey are all generic types. I think that MAP operation is to perform a method operation on each element of the collection, so its method may look like this:

func (ls List) Map(fk Function[string, string]) List {
  if fk == nil {
    return nil
  }
  var res List
  for _, nod := range ls {
    res = append(res, fk(nod))
  }
  return res
}

Complete interface

Similarly, if it is a general type, an interface needs to be supported, otherwise slices can be used with MAP, but other types cannot. Therefore, we add a definition of the interface, and the complete interface is as follows:

type Stream[T, F2, OUT any] interface {</code><code>  Filter(pre Predicate[T]) OUT</code><code>  Map(function Function[T, F2]) OUT</code><code>}

Following the same method above, I defined the Sorted method and the String Joins method, as follows:

type Stream[T, F2, OUT any] interface {
  Filter(pre Predicate[T]) OUT
  Map(function Function[T, F2]) OUT
}

Also, you need to add an interface, and the sorting of string slices is relatively simple. Here the method of string slicing is defined

Test it

ls := okgoarch.
    Filter(func(n string) bool { return n == "sparc64" || n == "mips64le" }).
    Map().
    Sorted(). //Sort by ascii code table    joins(":")
  ("%+v\n", 
  [arm arm64 loong64 mips64 mips64le ppc64 riscv64 sparc64]
ls)

String slices are OK, are there any other type possible

I tried to use a structure slice to illustrate the same idea and I directly posted the code:

type Person struct {
  Name string
  Age  int
}
type ByAgeNameCompare []Person
func (a ByAgeNameCompare) Len() int      { return len(a) }
func (a ByAgeNameCompare) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByAgeNameCompare) Less(i, j int) bool {
  if a[i].Age == a[j].Age {
    return a[i].Name < a[j].Name //DESC
  }
  return a[i].Age < a[j].Age //ASC
}
type Persons []Person
func (ls Persons) Sorted() Persons {
  (ByAgeNameCompare(ls))
  return ls
}
func (ls Persons) Filter(fk Predicate[Person]) Persons {
  if fk == nil {
    return nil
  }
  var res Persons
  for _, nod := range ls {
    if fk(nod) {
      res = append(res, nod)
    }
  }
  return res
}
func (ls Persons) Map(fk Function[Person, any]) any {
  if fk == nil {
    return nil
  }
  var res []any
  for _, nod := range ls {
    res = append(res, fk(nod))
  }
  return res
}
func (ls Persons) Map1(fk Function[Person, Person]) Persons {
  if fk == nil {
    return nil
  }
  var res Persons
  for _, nod := range ls {
    res = append(res, fk(nod))
  }
  return res
}

The above code is an implementation of the structure slice type. The structure type can be defined by itself, for example, the implementation of the stream stream interface of a certain subtype of JAVA

Complete code

type Predicate[P any] func(n P) bool
type Function[F any, OUT any] func(n F) OUT
type List []string
type Stream[T, F2, OUT any] interface {
  Filter(pre Predicate[T]) OUT
  Map(function Function[T, F2]) OUT
  Sorted() OUT
}
func (ls List) Filter(fk Predicate[string]) List {
  if fk == nil {
    return nil
  }
  var res List
  for _, nod := range ls {
    if fk(nod) {
      res = append(res, nod)
    }
  }
  return res
}
func (ls List) Map(fk Function[string, string]) List {
  if fk == nil {
    return nil
  }
  var res List
  for _, nod := range ls {
    res = append(res, fk(nod))
  }
  return res
}
func (ls List) joins(delim string) string {
  return (ls, delim)
}
func (ls List) Sorted() List {
  (ls)
  return ls
}
type Person struct {
  Name string
  Age  int
}
type ByAgeNameCompare []Person
func (a ByAgeNameCompare) Len() int      { return len(a) }
func (a ByAgeNameCompare) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByAgeNameCompare) Less(i, j int) bool {
  if a[i].Age == a[j].Age {
    return a[i].Name &lt; a[j].Name //DESC
  }
  return a[i].Age &lt; a[j].Age //ASC
}
type Persons []Person
func (ls Persons) Sorted() Persons {
  (ByAgeNameCompare(ls))
  return ls
}
func (ls Persons) Filter(fk Predicate[Person]) Persons {
  if fk == nil {
    return nil
  }
  var res Persons
  for _, nod := range ls {
    if fk(nod) {
      res = append(res, nod)
    }
  }
  return res
}
func (ls Persons) Map(fk Function[Person, any]) any {
  if fk == nil {
    return nil
  }
  var res []any
  for _, nod := range ls {
    res = append(res, fk(nod))
  }
  return res
}
func (ls Persons) Map1(fk Function[Person, Person]) Persons {
  if fk == nil {
    return nil
  }
  var res Persons
  for _, nod := range ls {
    res = append(res, fk(nod))
  }
  return res
}
func main() {
  var okgoarch = List{
    "arm",
    "arm64",
    "loong64",
    "mips64",
    "mips64le",
    "ppc64",
    "riscv64",
    "sparc64",
  }
  lss := okgoarch.
    Filter(func(n string) bool { return n == "sparc64" || n == "mips64le" })
  ("%+v\n", lss)
  ("%+v\n", okgoarch)
  ls := okgoarch.
    Filter(func(n string) bool { return n == "sparc64" || n == "mips64le" }).
    Map().
    Sorted(). //Sort by ascii code table    joins(":")
  ("%+v\n", ls)
  peoples := Persons{
    {"Alice", 30},
    {"Bob", 25},
    {"Charlie", 35},
    {"Dark", 75},
  }
  psvar := peoples.
    Filter(func(n Person) bool { return  != "Charlie" }).
    Map(func(n Person) any {
      return 
    })
  ("%+v\n", psvar)
  psvar1 := peoples.
    Filter(func(n Person) bool { return  != "Charlie" }).
    Map1(func(n Person) Person {
       =  + "pick"
      return n
    }).Sorted()
  ("%+v", psvar1)
}
[mips64le sparc64]
[arm arm64 loong64 mips64 mips64le ppc64 riscv64 sparc64]
MIPS64LE:SPARC64
[Alice Bob Dark]
[{Name:Bobpick Age:25} {Name:Alicepick Age:30} {Name:Darkpick Age:75}]

The above is the detailed content of the example of how GO simulates streaming operations. For more information about GO simulates streaming operations, please pay attention to my other related articles!