java8新特性:stream

一.demo1

1.代码

package stream._01;

import java.util.ArrayList;
import java.util.List;

public class App {

	public static void main(String[] args) {
		List<Apple> list = getApple();
		list.stream()
			.filter(a -> a.getWeight() == 100)
			.map(a -> {
				a.setWeight(a.getWeight() + 50);
				return a;
			})
			.sorted((a, b) -> a.getColor().length() - b.getColor().length())
			.forEach(System.out::println);
	}

	private static List<Apple> getApple() {
		List<Apple> list = new ArrayList<Apple>();
		list.add(new Apple("blue", 100));
		list.add(new Apple("red", 100));
		list.add(new Apple("red", 200));
		list.add(new Apple("green", 100));
		list.add(new Apple("green", 200));
		return list;
	}

}

class Apple {
	private String color;
	private Integer weight;

	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}

	public Apple(String color, Integer weight) {
		super();
		this.color = color;
		this.weight = weight;
	}

	public Integer getWeight() {
		return weight;
	}

	public void setWeight(Integer weight) {
		this.weight = weight;
	}

	@Override
	public String toString() {
		return "Apple [color=" + color + ", weight=" + weight + "]";
	}

}

2.输出

Apple [color=red, weight=150]
Apple [color=blue, weight=150]
Apple [color=green, weight=150]

3.分析

stream是一个流,有中间操作和终止操作,当一个流被中止了就不能复用了
像filter,map,sorted等都属于中间操作
foreach就给流终止掉了
像我的代码里写的一样
filter,map,sorted里面都是一些lambda表达式实现的函数式接口,可以很方便的实现对集合的各种操作
forEach里写的是方法引用,也是jdk8的一个新特性

二.demo2

1.代码

package stream._02;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class App {

	public static void main(String[] args) {
		List<Integer> list = new ArrayList<Integer>();
		for (int i = 0; i < 50000000; i++) {
			list.add(i);
		}
		System.setProperty("java.util.concurrent.ForkJoinPool.common.parallelism", "12");

		System.out.println(
				"设置的ForkJoinPool线程数:" + System.getProperty("java.util.concurrent.ForkJoinPool.common.parallelism"));

		Map<Long, Thread> map = new ConcurrentHashMap<Long, Thread>();
		list.parallelStream().forEach((i) -> {
			if (map.get(Thread.currentThread().getId()) == null) {
				map.put(Thread.currentThread().getId(), Thread.currentThread());
			}
		});

		if (map.size() > 13) {
			System.out.println("wtf");
		}

		System.out.println("实际的工作线程数(包括main):" + map.keySet().size());

		for (Long id : map.keySet()) {
			Thread t = map.get(id);
			System.out.println(t.getId() + ":" + t.getName());
		}

	}

}

2.输出

设置的ForkJoinPool线程数:12
实际的工作线程数(包括main):13
1:main
13:ForkJoinPool.commonPool-worker-9
14:ForkJoinPool.commonPool-worker-2
15:ForkJoinPool.commonPool-worker-11
16:ForkJoinPool.commonPool-worker-4
17:ForkJoinPool.commonPool-worker-13
18:ForkJoinPool.commonPool-worker-6
19:ForkJoinPool.commonPool-worker-15
20:ForkJoinPool.commonPool-worker-8
21:ForkJoinPool.commonPool-worker-1
22:ForkJoinPool.commonPool-worker-10
23:ForkJoinPool.commonPool-worker-3
24:ForkJoinPool.commonPool-worker-12

3.分析

stream可以非常方便的帮助我们实现对集合的多线程同步处理
parallelStream()会return一个并行流
这个流的并行线程是通过ForkJoinPool获得的,数量默认是cpu内核数-1(因为main线程也占一个)
也可以自己指定

需要注意的是,多线程中的处理要自己处理线程并发问题,如上述代码,如果改成HashMap,可能会得到不一样的结果
(更推荐的做法是lambda函数式编程应当不依赖外部条件,这样就不会有线程并发的问题)

你可能感兴趣的:(Java)