大佬教程收集整理的这篇文章主要介绍了Java8新特性----Stream,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_674_130@
/*
* Stream的三个操作步骤
*
* 1.创建stream
* 2.中间操作
* 3.终止操作(终端操作)
*
* */
@Test
void test()
{
//1.创建stream
//(1):可以通过collection系列集合提供的stream()或者parallelStream()
List<String> list=new ArrayList<>();
Stream<String> stream = list.stream();
//(2): 通过Arrays里面的静态方法stream()获取数据流
People[] peoples=new People[10];
Stream<People> stream1 = Arrays.stream(peoples);
//(3):通过stream里面的静态方法of()
Stream<String> aa = Stream.of("aa", "bb", "cc");
//(4):创建无限流
//迭代
Stream.iterate(0, (x) -> x + 2)
.limit(10)//中间操作
.forEach(System.out::println);
}
}
filter---接收Lambdac;从流中排除某些元素
limit(@H_134_139@max)---截断流c;使其元素不超过给定数量
skip(n)---跳过元素c;返回一个扔掉了前n个的元素的流c;若流张元素不足n个c;则返回一个空流c;与limit(n)互补
disTinct---筛选c;通过流所生成的元素的hashcode()和equals()去重复元素
使用演示:
public class TestMain
{
List<People> peopleList= Arrays.asList(
new People("1号",18,3000),
new People("2号",21,4000),
new People("3号",19,5000),
new People("4号",20,3500)
);
@Test
void test()
{
//中间操作不会执行任何操作
Stream<People> s=peopleList.stream().filter(people ->people.getAge()>19);
//终止操作:一次性执行全部内容c;即惰性求值
s.forEach(System.out::println);
}
}
//外部迭代
Iterator<People> iterator = peopleList.iterator();
while(iterator.hasNext())
System.out.println(iterator.next());
public class TestMain
{
List<People> peopleList= Arrays.asList(
new People("1号",18,3000),
new People("2号",21,4000),
new People("3号",19,5000),
new People("4号",20,3500)
);
@Test
void test()
{
//当查询到满足条件的两条数据后c;就停止迭代c;此行为称为短路
peopleList.stream().
filter(people ->{
System.out.println("短路");
return people.getAge()>15;}).
limit(2).//短路
forEach(System.out::println);
}
}
public class TestMain
{
List<People> peopleList= Arrays.asList(
new People("1号",18,3000),
new People("2号",21,4000),
new People("3号",19,5000),
new People("4号",20,3500)
);
@Test
void test()
{
peopleList.stream().
filter(people ->{
System.out.println("短路");
return people.getAge()>15;}).
skip(2).
forEach(System.out::println);
}
}
public class TestMain
{
List<People> peopleList= Arrays.asList(
new People("1号",18,3000),
new People("2号",21,4000),
new People("2号",21,4000),
new People("4号",20,3500)
);
@Test
void test()
{
peopleList.stream().
disTinct().
forEach(System.out::println);
}
}
@H_682_1333@map–接收Lambda,将元素转换为其他形式或提取信息c;接收一个函数作为参数c;该函数会被应用到每个元素上c;并将其映射成一个新的元素
flatMap—接收一个函数作为参数c;将流中的每个值都换成另一个流c;然后把所有流连接成一个流
@H_32_8@map的使用演示:public class TestMain
{
List<People> peopleList= Arrays.asList(
new People("1号",18,3000),
new People("2号",21,4000),
new People("2号",21,4000),
new People("4号",20,3500)
);
@Test
void test()
{
List<String> list=Arrays.asList("a","b","c");
//将原先集合里面的小写c;全部转换为大写c;并输出
list.stream().@H_852_144@map((x)->x.toUpperCase()).forEach(System.out::println);
//对原先的流是没有影响的
System.out.println(list);
System.out.println("------------------------------------------------");
// peopleList.stream().map(p->p.getName());
//将原先集合里面的People元素全部转换为String元素
peopleList.stream().@H_852_144@map(People::getName).forEach(System.out::println);
}
}
使用前c;先看一下下面这个案例:
void test()
{
List<String> list=Arrays.asList("aaa","bbb","ccc");
Stream<Stream<Character>> sm = list.stream().@H_852_144@map(TestMain::getAll);
//相当于当前sm大流里面存放了三个小流
sm.forEach(System.out::println);
}
public static Stream<Character> getAll(String str)
{
List<Character> list=new ArrayList<>();
for(Character ch:str.toCharArray())
{
list.add(ch);
}
return list.stream();
}
显然这里我们将list集合对应的新流中每一个元素c;都映射为了一个流c;并返回c;相当于现在的大流中有三个小流
下面我们需要遍历这些小流c;取出里面的值
void test()
{
List<String> list=Arrays.asList("aaa","bbb","ccc");
Stream<Stream<Character>> sm = list.stream().@H_852_144@map(TestMain::getAll);
//遍历大流的同时c;遍历小流c;取出小流中的值
sm.forEach(x-> x.forEach(System.out::println));//效果{{a,a,a},{B,b,b},{C,c,c}}
}
public static Stream<Character> getAll(String str)
{
List<Character> list=new ArrayList<>();
for(Character ch:str.toCharArray())
{
list.add(ch);
}
return list.stream();
}
显然上面写法比较复杂c;下面给出简化写法
@Test
void test()
{
List<String> list=Arrays.asList("aaa","bbb","ccc");
//返回值不在是大流嵌套小流c;而是一个流
Stream<Character> characterStream = list.stream()
.flatMap(TestMain::getAll);// 效果{a,a,a,b,b,b,c,c,c}
characterStream.forEach(System.out::println);
}
public static Stream<Character> getAll(String str)
{
List<Character> list=new ArrayList<>();
for(Character ch:str.toCharArray())
{
list.add(ch);
}
return list.stream();
}
List<String> list=Arrays.asList("aaa","bbb","ccc");
List list1=new ArrayList();
list1.add(list);
list1.addAll(list);
System.out.println(list1);
sorted()—自然排序(ComparablE)
sorted(Comparator com)—定制排序(Comparator)
List<People> peopleList= Arrays.asList(
new People("1号",18,3000),
new People("2号",21,4000),
new People("2号",21,4000),
new People("4号",18,3500)
);
@Test
void test()
{
//这里people没有实现Comparable接口c;因此没有自然排序的功能
//我们需要定制排序
peopleList.stream().sorted((x,y)->{
if(x.getAge()==y.getAge())
//money按照降序排列
return -x.@H_134_139@money.compareTo(y.getMoney());
else
return x.getAge().compareTo(y.getAge());
}).forEach(System.out::println);
}
查找与匹配
allMatch--检查是否匹配所有元素
anymatch---检查是否至少匹配一个元素
noneMatch---检查是否没有匹配所有元素
findFirst---返回第一个元素
findAny---返回当前流中任意元素
count---返回流中元素的总个数
max----返回流中最大值
min---返回流中最小值
演示:
public class TestMain
{
List<People> peopleList= Arrays.asList(
new People("1号",18,3000, People.STATUS.BUSY),
new People("2号",21,4000, People.STATUS.FREE),
new People("2号",21,4000, People.STATUS.BUSY),
new People("4号",18,3500, People.STATUS.BUSY)
);
/*
allMatch--检查是否匹配所有元素
anymatch---检查是否至少匹配一个元素
noneMatch---检查是否没有匹配所有元素
findFirst---返回第一个元素
findAny---返回当前流中任意元素
count---返回流中元素的总个数
max----返回流中最大值
min---返回流中最小值*/
@Test
void test()
{
Boolean ret = peopleList.stream().allMatch(x -> x.getStatus().equals(People.STATUS.BUSY));
System.out.println(ret);
Boolean ret1 = peopleList.stream().anymatch(x -> x.getStatus().equals(People.STATUS.FREE));
System.out.println(ret1);
Boolean ret2 = peopleList.stream().noneMatch(x -> x.getStatus().equals(People.STATUS.BUSY));
System.out.println(ret2);
//得到第一个元素
Optional<People> first = peopleList.stream().sorted((x, y) -> -x.getMoney().compareTo(y.getMoney())).findFirst();
System.out.println(first.get());
//得到当前流中的任意一个元素
//parallelStream:多线程并行查找
Optional<People> any = peopleList.parallelStream().filter(x -> x.getStatus().equals(People.STATUS.FREE)).findAny();
System.out.println(any.get());
//元素总个数
long count = peopleList.stream().count();
System.out.println(count);
//返回流中最大值和最小值
Optional<People> max = peopleList.stream().@H_852_144@max((x, y) -> -x.getMoney().compareTo(y.getMoney()));
System.out.println(@H_134_139@max.get());
//获取当前最小的金钱数
Optional<Integer> min = peopleList.stream().@H_852_144@map(People::getMoney).@H_852_144@min(Integer::compareTo);
System.out.println(@H_134_139@min.get());
}
}
@H_450_3480@
public class TestMain
{
List<People> peopleList= Arrays.asList(
new People("1号",18,3000, People.STATUS.BUSY),
new People("2号",21,4000, People.STATUS.FREE),
new People("2号",21,4000, People.STATUS.BUSY),
new People("4号",18,3500, People.STATUS.BUSY)
);
@Test
void test()
{
// T reduce(T identity, BinaryOperator<T> accumulator);
//这里可以使用ClassName::MethodName的原因是 Function<T, R>c;比getMoeny多一个参数c;且第一个参数类型为People
Integer sum = peopleList.stream().@H_852_144@map(People::getMoney).reduce(0, (x, y) -> x + y);//0是起始累加值
System.out.println("money总和为:"+sum);
}
}
也可以不指定起始值c;但是这样可能数据为空c;因此会被封装为一个Optional对象
public class TestMain
{
List<People> peopleList= Arrays.asList(
new People("1号",18,3000, People.STATUS.BUSY),
new People("2号",21,4000, People.STATUS.FREE),
new People("2号",21,4000, People.STATUS.BUSY),
new People("4号",18,3500, People.STATUS.BUSY)
);
@Test
void test()
{
// T reduce(T identity, BinaryOperator<T> accumulator);
Optional<Integer> reduce = peopleList.stream().@H_852_144@map(People::getMoney).reduce((x, y) -> x + y);
System.out.println("money总和为:"+reduce.get());
}
}
这里不一定非要是数的累加c;也可以是字符串的反复拼接
.reduce("",String::contact);
collect----将流转换为其他形式c;接收一个Collector接口的实现c;用于给Stream中元素做汇总的方法
演示:public class TestMain
{
List<People> peopleList= Arrays.asList(
new People("aaa",18,3000, People.STATUS.BUSY),
new People("bbb",21,4000, People.STATUS.FREE),
new People("ccc",21,4000, People.STATUS.BUSY),
new People("ddd",18,3500, People.STATUS.BUSY)
);
@Test
void test()
{
//结果收集到map中
@H_71_157@map<String, String> collect = peopleList.stream().@H_852_144@map(People::getName)
//指定key和value,这里的key是name字符串转大写c;value就是name字符串本身不变
.collect(Collectors.toMap(x -> x.toUpperCase(), y -> y));
System.out.println(collect);
System.out.println("==============================");
//结果收集到List中
List<String> StringList = peopleList.stream().@H_852_144@map(People::getName).collect(Collectors.toList());
System.out.println(StringList);
System.out.println("==============================");
//结果收集到HashSet中
HashSet<String> collect1 = peopleList.stream().
@H_852_144@map(People::getName).collect(Collectors.toCollection(HashSet::new));
System.out.println(collect1);
}
}
collect的其他一些用法
public class TestMain
{
List<People> peopleList= Arrays.asList(
new People("aaa",18,3000, People.STATUS.BUSY),
new People("bbb",21,4000, People.STATUS.FREE),
new People("ccc",21,4000, People.STATUS.BUSY),
new People("ddd",18,3500, People.STATUS.BUSY)
);
@Test
void test()
{
//计算当前流中元素的总数
Long sum = peopleList.stream().collect(Collectors.counTing());
System.out.println("当前流中元素的总数:"+sum);
//计算工资平均值
Double @H_71_157@moneyAvg = peopleList.stream().collect(Collectors.averagingInt(People::getMoney));
System.out.println("工资平均值:"+@H_71_157@moneyAvg);
//计算年龄的所有信息
IntSumMaryStatistics age = peopleList.stream().collect(Collectors.summarizingInt(People::getAge));
System.out.println("年龄所有相关的信息:"+age);
//计算年龄的总和
Integer ageSUm = peopleList.stream().collect(Collectors.summingInt(People::getAge));
System.out.println(ageSUm);
//计算工资最大值
Optional<Integer> moneymax = peopleList.stream().@H_852_144@map(People::getMoney).collect(Collectors.@H_852_144@maxBy((x,y)->Integer.compare(x,y)));
System.out.println("最高工资:"+@H_134_139@moneyR_718_11845@ax.get());
//计算最低工资
Optional<Integer> moneymin = peopleList.stream().@H_852_144@map(People::getMoney).collect(Collectors.@H_852_144@minBy(Integer::compare));
System.out.println("最低工资:"+@H_134_139@moneyR_718_11845@in.get());
}
}
单级分组:
public class TestMain
{
List<People> peopleList= Arrays.asList(
new People("aaa",18,3000, People.STATUS.BUSY),
new People("bbb",21,4000, People.STATUS.FREE),
new People("ccc",21,4000, People.STATUS.FREE),
new People("ddd",18,3500, People.STATUS.BUSY)
);
@Test
void test()
{
//单级分组
@H_71_157@map<People.STATUS, List<People>> collect = peopleList.stream().collect(Collectors.groupingBy(People::getStatus));
System.out.println(collect);
}
}
多级分组:
public class TestMain
{
List<People> peopleList= Arrays.asList(
new People("aaa",18,3000, People.STATUS.BUSY),
new People("bbb",21,4000, People.STATUS.FREE),
new People("ccc",21,10000, People.STATUS.FREE),
new People("ddd",18,12000, People.STATUS.BUSY)
);
@Test
void test()
{
//先按照状态分组c;再按照money分组
@H_71_157@map<People.STATUS, @H_71_157@map<String, List<People>>> collect = peopleList.stream().collect(Collectors.groupingBy(People::getStatus, Collectors.groupingBy(
x -> {
if (x.getMoney() >= 10000)
return "有钱人";
else
return "穷人";
}
)));
System.out.println(collect);
}
}
public class TestMain
{
List<People> peopleList= Arrays.asList(
new People("aaa",18,3000, People.STATUS.BUSY),
new People("bbb",21,4000, People.STATUS.FREE),
new People("ccc",21,10000, People.STATUS.FREE),
new People("ddd",18,12000, People.STATUS.BUSY)
);
@Test
void test()
{
//按照true or false进行分区
@H_71_157@map<Boolean, List<People>> ret = peopleList.stream().collect(Collectors.partitioningBy(x -> x.getMoney() >= 10000));
System.out.println(ret);
}
}
public class TestMain
{
List<People> peopleList= Arrays.asList(
new People("aaa",18,3000, People.STATUS.BUSY),
new People("bbb",21,4000, People.STATUS.FREE),
new People("ccc",21,10000, People.STATUS.FREE),
new People("ddd",18,12000, People.STATUS.BUSY)
);
@Test
void test()
{
IntSumMaryStatistics collect = peopleList.stream().collect(Collectors.summarizingInt(People::getMoney));
System.out.println(collect);
System.out.println(collect.getMax());
System.out.println(collect.getCount());
}
}
public class TestMain
{
List<People> peopleList= Arrays.asList(
new People("aaa",18,3000, People.STATUS.BUSY),
new People("bbb",21,4000, People.STATUS.FREE),
new People("ccc",21,10000, People.STATUS.FREE),
new People("ddd",18,12000, People.STATUS.BUSY)
);
@Test
void test()
{
//第一个参数是连接字符串时分割的符合c;后面两个参数依次是前缀和后缀
String ret = peopleList.stream().@H_852_144@map(People::getName).collect(Collectors.joining(",", "==", "=="));
System.out.println(ret);
}
}
并行流 : 就是把一个内容分成多个数据块c;并用不同的线程分 别处理每个数据块的流。
Java 8 中将并行进行了优化c;我们可以很容易的对数据进行并 行操作。Stream API 可以声明性地通过 parallel() 与 sequential() 在并行流与顺序流之间进行切换。
Fork/Join 框架 : 就是在必要的情况下c;将一个大任务c;进行拆分(fork)成若干个 小任务(拆到不可再拆时)c;再将一个个的小任务运算的结果进行 join 汇总.
采用 “工作窃取”模式(work-stealing): 当执行新的任务时它可以将其拆分分成更小的任务执行c;并将小任务加到线 程队列中c;然后再从一个随机线程的队列中偷一个并把它放在自己的队列中。
相对于一般的线程池实现c;fork/join框架的优势体现在对其中包含的任务的 处理方式上.在一般的线程池中c;如果一个线程正在执行的任务由于某些原因 无法继续运行,那么该线程会处于等待状态。而在fork/join框架实现中c;如果 某个子问题由于等待另外一个子问题的完成而无法继续运行.那么处理该子 问题的线程会主动寻找其他尚未运行的子问题来执行。这种方式减少了线程 的等待时间c; 高了性能。
创建一个ForkJoinCalculate计算类:
public class ForkJoinCalculate extends RecursiveTask<Long> {
private long start;
private long end;
private static final long THRESHOLD = 1000000;
public ForkJoinCalculate(long start, long end) {
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
long length = end - start;
if (length <= THRESHOLD) {
long sum = 0;
for (long i = start; i <= end; i++) {
sum += i;
}
return sum;
}else {
long middle = (start + end) / 2;
ForkJoinCalculate left = new ForkJoinCalculate(start, middle);
left.fork();
ForkJoinCalculate right = new ForkJoinCalculate(@H_134_139@middle + 1, end);
right.fork();
return left.join() + right.join();
}
}
}
测试方法:
private static final long END_VALUE = 10000000000L;
// fork join
@Test
public void test1(){
Instant start = Instant.now();
ForkJoinPool pool = new ForkJoinPool();
ForkJoinTask<Long> task = new ForkJoinCalculate(0, END_VALUE);
Long sum = pool.invoke(task);
System.out.println(sum);
Instant end = Instant.now();
System.out.println("耗时:" + Duration.between(start, end).toMillis());
}
执行结果:
-5340232216128654848
耗时:2325
使用普通for 循环:
@Test
public void test2(){
Instant start = Instant.now();
long sum = 0L;
for (long i = 0; i <= END_VALUE; i ++){
sum += i;
}
System.out.println(sum);
Instant end = Instant.now();
System.out.println("耗时:" + Duration.between(start, end).toMillis());
}
执行结果:
-5340232216128654848
耗时:3571
//java8 的并行流测试
@Test
public void test3(){
Instant start = Instant.now();
LongStream.rangeClosed(0, END_VALUE)
.parallel()
.reduce(0, Long::sum);
Instant end = Instant.now();
System.out.println("耗时为:" + Duration.between(start, end).toMillis());
}
执行结果:
耗时为:1690
检查本机的可用处理器数:
// 可用处理器
@Test
public void test4(){
int num = Runtime.getRuntime().availableProcessors();
System.out.println(num);
}
执行结果:
8
Java 8 Optional的正确姿势
以上是大佬教程为你收集整理的Java8新特性----Stream全部内容,希望文章能够帮你解决Java8新特性----Stream所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。