实现前端实现多国语言切换 = 实现前端页面的资源国际化,需要依赖jQuery.i18n.properties插件[TOC]
Stream 简单介绍
java8中引入了一个新的特性Stream(流)
官方介绍:A sequence of elements supporting sequential and parallel aggregate operations.(支持顺序和并行聚合操作的一系列元素)
聚合:在信息科学中是指对有关的数据进行内容挑选、分析、归类,最后分析得到人们想要的结果(百度百科)
1、如何产生一个Stream
@Test
public void createStream() {
Collection list = new ArrayList();
Map map = new HashMap();
Object[] intArray = {1,2,3,4,5};
//集合产生流
Stream listStream = list.stream();
Stream listParallelStream = list.parallelStream();
//数组产生流
Stream mapStream = Arrays.stream(intArray);
File file = new File("stream.txt");
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
//从文件读取数据形成流
Stream<String> lineStream = bufferedReader.lines();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
2、Stream的操作
Stream的操作分为两大类,一类是 中间操作 ,不会立即执行,只是返回一个新的Stream,这个新的Stream记录了上一步的操作。另一类是 终端操作 ,最终操作会使用Stream,真正的执行之前的中间操作,并且完成终端里的具体操作。(比如将结果封装到一个List里面)
2.1、中间操作(Intermediate operations)
//无状态的操作
list.stream().filter(Objects::nonNull).map(String::toLowerCase).forEach(System.out::println);
//有状态的操作
list.stream().distinct().sorted().forEach(System.out::println);
上面的 filter,map 都是中间操作。filter 表示过滤掉为null的值,map 表示将string装化为小写字母,它们都接受一个Lambda。
无状态的操作, 像filter,map都是无状态的操作, 处理一个新的元素时不需要获得先前遍历过的元素的状态。
有状态的操作,像distinct, sorted, 需要得到先前访问的元素的状态。
有状态的操作在产生结果前需要获得完整的输入。 因此有状态的操作一个并行流时, 可能需要多次传入数据或者需要缓存数据。 而无状态的操作只需传入一次数据。 所以并行流处理有状态的操作时可能比序列化流使用更多的时间
常用的中间操作说明
状态 | 函数 | 作用 |
---|---|---|
AAAAA | AAAAAAAAAAAAAAAAAAAAAAAAAAAA | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA |
无状态 | filter(Predicate p) | 接收Lambda,从流中排除某些元素 |
无状态 | limit(long maxSize) | 截断流,使其元素不超过给定数量 |
无状态 | skip(long n) | 跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流。与limit(n)互补 |
无状态 | map(Function f) | 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素 |
无状态 | flatMap(Function f) | 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流 |
有状态 | sorted(Conparator comp) | 产生一个新流,其中按照比较器顺序排序 |
有状态 | sorted() | 产生一个新流,其中按自然顺序排序 |
有状态 | distinct() | 筛选,通过流所生成元素的hashCode()和equals()去除重复的元素 |
2.2、终端操作(Terminal operations)
//打印出不为null的,大写字母的小写
list.stream().filter(Objects::nonNull).map(String::toLowerCase).forEach(System.out::println);
//将不为Null的小写字母封装进一个map
List resultList = list.stream().filter(Objects::nonNull).map(String::toLowerCase).collect(Collectors.toList());
//根据list中的数据,过滤后是否有元素匹配"a",如果有返回true,没有返回false
boolean b = list.stream().filter(Objects::nonNull).map(String::toLowerCase).anyMatch(s -> s.equals("a"));
终端操作又可以分为短路与非短路操作,这个应该很好理解,前者是指遇到某些符合条件的元素就可以得到最终结果;而后者是指必须处理所有元素才能得到最终结果。
常用的终端操作说明
函数 | 作用 |
---|---|
AAAAAAAAAAAAAAAAAAAA | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA |
allMatch(Predicate p) | 检查是否匹配所有元素 |
anyMatch(Predicate p) | 检查是否至少匹配一个元素 |
noneMatch(Predicate p) | 检查是否没有匹配所有元素 |
findFirst() | 返回第一个元素 |
findAny() | 返回当前流中的任意元素 |
count() | 返回流中元素的总数 |
max(Comparator c) | 返回流中的最大值 |
min(Comparator c) | 返回流中的最小值 |
reduce(BinaryOperator b) | 返回值是Optional封装的对象 |
reduce(T identity, BinaryOperator b) | 可以将流中元素结合起来,得到一个值。默认返回 identity |
collect(Collector collector) | 将数据源经过过滤、筛选等操作收集到对应的集合或者Map,或者收集他们的统计信息,如求和、平均值、最大值、最小值、记录数等 |
2.3、Stream的特点
- 不存储数据:流不是一个存储元素的数据结构。 它只是传递源(source)的数据。
- 功能性的(Functional in nature)。 在流上操作只是产生一个结果,不会修改源。 例如filter只是生成一个筛选后的stream,不会删除源里的元素。
- 延迟搜索。 许多流操作, 如filter, map等,都是延迟执行。 中间操作总是lazy的。
- Stream可能是无界的。 而集合总是有界的(元素数量是有限大小)。 短路操作如limit(n) , findFirst()可以在有限的时间内完成在无界的stream
- 消费品。流的元素在流的声明周期内只能访问一次。 再次访问只能再重新从源中生成一个Stream
3、使用流的好处
- 代码编写简洁
- 集合操作很方便
- 并发处理,使用 Fork/Join 模式(注意,一些有状态的中间操作使用并发处理会更慢)
@Before
public void init() {
Random random = new Random();
list = Stream.generate(() -> random.nextInt(100)).limit(100000000).collect(toList());
}
/**
* 测试并行流
*/
@Test
public void testParallel() {
long begin1 = System.currentTimeMillis();
long num_1 = list.stream().filter(x->(x > 10)).count();
long end1 = System.currentTimeMillis();
System.out.println(num_1);
System.out.println("未使用并行流:" + (end1-begin1));
long num_2 = list.stream().parallel().filter(x->(x > 10)).count();
long end2 = System.currentTimeMillis();
System.out.println(num_2);
System.out.println("使用并行流:" + (end2-end1));
}
//测试结果:
//89001550
//未使用并行流:412
//89001550
//使用并行流:125
网友评论