这篇文章主要讲解下JAVA1.8中Stream的使用,再次之前先说明下,在学习任何一个技术之前,都要事先去了解它。网上很多都麻木的说,stream流支持并行比循序执行快很多,性能更好;for循环性能更好......
Stream流性能分析,这篇文章写的很详细,推荐看看
大致结论:
1、for更快的原因:for循环对于基础数据数组操作来说(例如int[]),性能是无疑比stream快的,因为对于基础数组是直接的内存访问,之前也说过,数组在内存是连续存储空间,所以for循环对于它的索引查找是很快的,初次之外,还涉及到CPU高级缓存,JIT优化等等。
2、for不总是远超Stream:如果应用于序列中每个元素的功能是 CPU 密集型的,则性能数据会发生显着变化,如果功能严重受 CPU 限制,则 for 循环和顺序流之间不再有可测量的差异(缩小差距)。比如:ArrayList的使用,因为ArrayList等集合中的元素是通过迭代器访问的,所以有相应的性能开销。
3、并行流不一定比顺序流快:通常来说并行流的使用,会比顺序流性能更加快,这是取决于服务器配置,为了充分利用cpu性能,并行流更加高效。但是这种结论也并不是完全正确的,第一、并行流线程之类的也会额外的进行性能开销,第二、比如distinct()操作,它的状态将被多个工作线程并发访问,这需要某种形式的协调或同步,这会增加开销,这会减慢并行执行的速度,直到并行执行可能比顺序执行慢得多执行。
下面就主要说下stream的使用:
1、获取Stream流
Stream<Object> stream = objects.stream();
Stream<Object> stream0 = Stream.of(objects);
2、返回一个空的顺序
Stream<Object> empty = Stream.empty();
3、generate(Supplier) 返回无限顺序无序流,其中每个元素由提供的 Supplier(函数时接口,返回Object)
/** 案例:无线生成随机数字10以内数据*/
Supplier supplier = new Supplier() {
@Override
public Object get() {
return new Random().nextInt(10);
}
};
Stream<Integer> generate0 = Stream.generate(supplier).limit(10);
// lambda写法
Stream<Integer> generate = Stream.generate(() -> {
return new Random().nextInt(10);
}).limit(10);
4、iterate(Integer,UnaryOperator)返回有序无限连续 StreamXNTest : seed -- 从seed开
/**案例:从0开始,返回+2 有序的流*/
UnaryOperator unaryOperator =new UnaryOperator() {
@Override
public Object apply(Object seed) {
return (int)seed+2;
}
};
Stream<Integer> iterate = Stream.iterate(0,unaryOperator).limit(20);
// lambda
Stream<Integer> iterate0 = Stream.iterate(0, n -> n+2).limit(20);
5、allMatch(Predicate) 返回此流的【所有元素】是否与提供的谓词匹配。 - 返回值:boolean
Object o :o为数组数据,遍历比较
Predicate predicate =new Predicate() {
@Override
public boolean test(Object o) {
System.out.println(o.equals("Jxh"));
return o.equals("Jxh");
}
};
boolean flag = objects.stream().allMatch(predicate);
// lambda
boolean flag0 = objects.stream().allMatch(x -> x.equals("Caomm"));
6、anyMatch(Predicate) 返回此流的【任一一个元素】是否与提供的谓词匹配 -- 返回值:boolean
boolean flag0 = objects.stream().anyMatch(x -> x.equals("Caomm"));
7、count() 返回此流中的元素数
long count = objects.stream().count();
System.out.println(count);
8、distinct() 返回由该流的不同元素,返回值:StreamXNTest
Stream<String> distinct = objects.stream().distinct();
9、findFirst() 第一个元素的Optional,如果流为空,则返回一个空的Optional
Optional<String> first = objects.stream().findFirst();
// 如果存在值first.isPresent()返回true,否则返回false
if (first.isPresent()) {
// 如果 Optional中有一个值,返回值,否则抛出 NoSuchElementException
first.get();
//System.out.println(first.get());
}
10、findAny() 返回任意一个元素的Optional,如果流为空,则返回一个空的Optional
描述: 就是返回流程中的任意一个元素,如果时串行流,基本上就是返回第一个找到的元素 如果时并行流,那就从获取的值里面返回任意一个元素了
//Optional<Object> first0 = objects.stream().findAny();
Optional<String> first0 = objects.stream().parallel().findAny(); // 开启并行流
// 如果存在值first.isPresent()返回true,否则返回false
if (first0.isPresent()) {
// 如果 Optional中有一个值,返回值,否则抛出 NoSuchElementException
first0.get();
//System.out.println(first0.get());
}
11、filter(Predicate) 返回由与此给定谓词匹配的此流的元素组成的流 -- 返回值:Stream
Predicate predicate = new Predicate() {
// Object o : o为集合中元素,遍历获取相同的元素
@Override
public boolean test(Object o) {
return o.equals("Jxh");
}
};
Stream<Object> objectStream = objects.stream().filter(predicate);
// lambda
Stream<String> objectStream = objects.stream().filter(x -> x.equals("Jxh"));
12、map 返回由给定函数应用于此流的元素的结果组成的流
个人:就是返回stream元素,可以通过此方法对元素修改
Function function = new Function() {
@Override
public Object apply(Object o) {
return o+"001";
}
};
Stream stream = objects.stream().map(function);
Stream stream = objects.stream().map(x -> x+"001");
13、collect() 收集器
个人:将数组流,以指定的方式收集起来,一般来说操作数据流不会改变数据流类型,可以通过collect对数据结构进行改变
// Collectors.joining(",") 将数组元素使用","进行连接
String result = objects.stream().collect(Collectors.joining(","));
System.out.println(result);
// Collectors.joining(",") 将数组元素使用","进行连接,并在使用{}包括
String result0 = objects.stream().collect(Collectors.joining(",", "{", "}"));
System.out.println(result0);
// 对数组流进行指定元素分组
List<Map<String, Object>> data = Data.getData();
Map<Object, List<Map<String, Object>>> datad = data.stream().collect(Collectors.groupingBy(x -> x.get("address")));
System.out.println(datad);