java如何创建一个流_说说在 Java 中如何创建流

1 元素转换为流

通过 Stream.of() ,我们可以很容易地将一组元素转化成流。

Stream.of("今天", "是", "个", "好日子").forEach(System.out::println);

System.out.println();

Stream.of(23, 29.2, 291.8).forEach(System.out::println);

运行结果:

今天

好日子

23

29.2

291.8

ac4fa736a353

2 集合转换为流

每种集合都可以通过调用 stream() 方法来产生一个流。 Bruce Eckel 举了这样一个示例:

List bubbles = Arrays.asList(new Bubble(1), new Bubble(2), new Bubble(3));

System.out.println(bubbles.stream().mapToInt(b -> b.i).sum());

System.out.println();

Set set = new HashSet<>(Arrays.asList("It's a wonderful day".split(" ")));

set.stream().map(x -> x + " ").forEach(System.out::println);

System.out.println();

Map map = new HashMap<>();

map.put("pi", 3.14);

map.put("e", 2.71);

map.put("phi", 1.618);

map.entrySet().stream().map(e -> e.getKey() + ": " + e.getValue()).forEach(System.out::println);

运行结果:

6

a

It's

wonderful

day

phi: 1.618

e: 2.71

pi: 3.14

其中 Bubble 的定义是:

public class Bubble {

public final int i;

public Bubble(int i) {

this.i = i;

}

@Override

public String toString() {

return "Bubble(" +

"" + i +

')';

}

private static int count = 0;

public static Bubble bubbler() {

return new Bubble(count++);

}

}

示例中的 mapToInt() 方法会将一个对象流(object stream)转换成为包含整型数字的 IntStream。同样,针对 Float 和 Double 也有类似名字的转换方法。

为了从 Map 集合中产生流数据,我们首先调用 entrySet() 产生一个对象流,这个对象流中的每个对象都包含一个 key 以及与其相关联的 value ,通过调用 getKey() 和 getValue() 就可以获得相应的值。

示例中的 PHI 被认为是世界上最美丽的数字。

PHI源于斐波那契数列(1-1-2-3-5-8-13-21-……)这个数列之所以非常有名,不仅是因为数列中相邻两项之和等于后一项,而且相邻的两项相除所得的商也约等于1.618。

PHI 还有一点奇妙之处是其比例与其倒数是一样的。1.618的倒数是0.618,而1.618:1与1:0.618计算结果相同。

在自然界,人们发现鹦鹉螺身上每圈罗纹的直径与相邻罗纹直径之比是 PHI。

ac4fa736a353

通过连接穿过黄金分割点的弧线,就称为“黄金螺旋线”。

ac4fa736a353

建筑设计上,雅典城卫城供奉庇护神雅典娜的巴特农神殿,其正立面的长与宽之比为黄金比。

ac4fa736a353

据说,最早发现这个优美比例的是古希腊的毕达哥拉斯学派 . 他们曾不厌其烦地把线段 一段一段地分成不同的两截,反复改变着比例并加以比较,最后才找到了这个 “ 最优雅的比例 ”。

但是把这个比例冠以 “ 黄金 ” 二字的美名则开始于意大利著名科学家 与艺术家达芬奇。 从此,0.618作为黄金比统治着当时欧洲的建筑和艺术,并影响到人们生活的许多方面,一直延续至今。

达芬奇的《蒙娜丽莎》就是严格按照黄金比例进行设计绘制的典范。

ac4fa736a353

在视觉上,黄金分割本质上带来的是和谐(相似、重复、联系),以及变化(运动、活力),通过这两点,带给人以美的享受。

3 创建数组流

ac4fa736a353

可以利用 Arrays 类中的 stream() 静态方法,把数组转换为流。

Arrays.stream(new double[]{3.14, 2.71, 1.618}).forEach(n -> System.out.format("%f ", n));

System.out.println();

Arrays.stream(new int[]{3, 2, 1}).forEach(n -> System.out.format("%d ", n));

System.out.println();

Arrays.stream(new long[]{13, 12, 11}).forEach(n -> System.out.format("%d ", n));

System.out.println();

Arrays.stream(new int[]{3, 2, 1, 0, -1, -2}, 3, 6).forEach(n -> System.out.format("%d ",

n));

运行结果:

3.140000 2.710000 1.618000

3 2 1

13 12 11

0 -1 -2

最后一个示例展示了如果设定数组范围。Arrays.stream() 方法还定义了两个额外参数。第一个参数是数组起始位置(包含),第一个参数是数组终止位置(不包含)。

4 循环遍历创建流

IntStream 类提供了 range() 方法用于生成整型序列的流。很适合编写循环:

//传统

int result = 0;

for (int i = 10; i < 20; i++) {

result += i;

}

System.out.println(result);

//for-in 循环

result = 0;

for (int i : range(10, 20).toArray())

result += i;

System.out.println(result);

//使用流

System.out.println(range(10, 20).sum());

运行结果:

145

145

145

第一种方式是传统编写 for 循环的方式;

第二种方式是使用 range() 创建流,接着将其转化为数组,最后在 for-in 代码块中使用;

相对来说,第三种方式最好。使用 range() 创建流之后,对流中的数字进行求和(sum)。

5 for 循环工具类

Bruce Eckel 利用 range 与 forEach 方法,实现了一个 for 循环工具类:

public class Repeat {

public static void repeat(int n, Runnable action) {

range(0, n).forEach(i -> action.run());

}

}

public class Looping {

static void hi() {

System.out.println("Hi!");

}

public static void main(String[] args) {

repeat(3, () -> System.out.println("Looping!"));

repeat(2, Looping::hi);

}

}

运行结果:

Looping!

Looping!

Looping!

Hi!

Hi!

该工具类让循环变得更加清晰。

ac4fa736a353

6 迭代创建流

Stream.iterate() 以种子(第一个入参)作为起始值,该值会传递给 UnaryOperator(第二个入参)。UnaryOperator 的返回结果会添加到流中,并且会把结果值作为下一次迭代方法的初始入参。

我们可以利用 iterate() 生成一个斐波那契数列。

public class Fibonacci {

int x = 1;

Stream numbers() {

return Stream.iterate(0, i -> {

// System.out.format("i -> %s\n",i);

// System.out.format("x -> %s\n",x);

int result = x + i;

x = i;

// System.out.format("result -> %s\n\n",result);

return result;

});

}

public static void main(String[] args) {

new Fibonacci().numbers()

.skip(20)//丢弃前 20 个

.limit(10)//然后再取 10 个

.forEach(System.out::println);

}

}

运行结果:

6765

10946

17711

28657

46368

75025

121393

196418

317811

514229

ac4fa736a353

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值