# 编程修炼 | Scala中Stream的应用场景及其实现原理

```def randomList = (1 to 50).map(_ => Random.nextInt(100)).toList
def isDivisibleBy3(n: Int) = {
val isDivisible = n % 3 == 0
println(s"\$n \$isDivisible")
isDivisible
}
randomList.filter(isDivisibleBy3).take(2)```

```  def first2UsingMutable: List[Int] = {
val result = ListBuffer[Int]()
randomList.foreach(n => {
if (isDivisibleBy3(n)) result.append(n)
if (result.size == 2) return result.toList
})
result.toList
}```

```  def first2UsingFold: List[Int] = {
randomList.foldLeft(Nil: List[Int])((acc, n) => {
if (acc.size == 2) return acc
if (isDivisibleBy3(n)) n :: acc
else acc
})
}```

randomList.toStream.filter(isDivisibleBy3).take(2).toList

MyStream(randomList: _*).filter(isDivisibleBy3).take(2).toList

```trait MyStream[+A] {

. . . . . .
}
case object Empty extends MyStream[Nothing]
case class Cons[+A](h: () => A, t: () => MyStream[A]) extends MyStream[A]```

Cons(()=>1,()=>Cons(()=>2,()=>Empty))

Smart初始化

```object MyStream {

def apply[A](elems: A*): MyStream[A] = {
if (elems.isEmpty) empty
}
def cons[A](hd: => A, tl: => MyStream[A]): MyStream[A] = {
lazy val tail = tl
Cons(() => head, () => tail)
}
def empty[A]: MyStream[A] = Empty
}```

MyStream(randomList: _*).filter(isDivisibleBy3).take(2).toList

filter

```trait MyStream[+A] {
def filter(p: A => Boolean): MyStream[A] = {
this match {
case Cons(h, t) =>
if (p(h())) cons(h(), t().filter(p))
else t().filter(p)
case Empty => empty
}
}
. . . . . .

}
```

take

MyStream(randomList: _*).filter(isDivisibleBy3).take(2)

```trait MyStream[+A] {
. . . . . .
def take(n: Int): MyStream[A] = {
if (n > 0) this match {
case Cons(h, t) if n == 1 => cons(h(), MyStream.empty)
case Cons(h, t) => cons(h(), t().take(n - 1))
case _ => MyStream.empty
}
else MyStream()
}
. . . . . .
}```

toList

```trait MyStream[+A] {
. . . . . .
def toList: List[A] = {
this match {
case Cons(h, t) => h() :: t().toList
case Empty => Nil
}
}
}```

• List(1,2,3)会构造一个容器，容器中包含数据
• List(1,2,3).filter(n=>n>1)会构造出一个新的容器，其中包含2和3，这两块具体的数据
• List(1,2,3).filter(n=>n>1).take(1)会把上一步中构造成的容器中的第一块数据取出，放入一个新容器
• MyStream(1,2,3)也会构造一个容器，但是这个容器中不包含数据，它包含能够生产数据的算法
• MyStream(1,2,3).filter(n=>n>1)也会构造出一个新的容器，这个容器中所包含的仍然是算法，是基于上一步构造出的能生产1，2，3的算法之上的判断数字是否大于1的算法
• MyStream(1,2,3).filter(n=>n>1).take(1)会把上一步中构造成的算法容器中的第一个算法取出，放入一个新容器
• MyStream(1,2,3).filter(n=>n>1).take(1).toList终于把上面所有步骤构造出的算法执行了，从而得到了最终想要的结果

147 篇文章43 人订阅

0 条评论

## 相关文章

### 第7章 面向对象编程（OOP）

7.2 类与继承 7.2.1 类 7.2.1.1 抽象类 7.2.1.2 接口 7.2.1.3 枚举 7.2.1.4 注解 7.2.1.5 静态类与...

581

1735

823

1475

1K2

2459

821

1946

1727

3445