每次看我一位同学(xx苛)的代码,总是让人感觉舒服高级,自己却怎么也写不出那种感觉,对他的崇拜之情自然不言而喻。所以呢,在询问下,他向我推荐了java8新特性中的流式编程,一直想学,正巧今日时间充足,因此从网上找到了两篇我认为非常棒的博客来进行学习,其中我本人也将其中的代码全部写了一遍,思路也从极乱到豁然开朗,所以特拿来分享(博客链接及代码)。
首先,在学习流式编程前,首先应当知道同样为Java8中新特性的lambda表达式,相信编程基础还不错的同学在python或其他语言中也了解过,这里我只贴出一篇学习博客:
https://www.cnblogs.com/haixiang/p/11029639.html
,里面的内容介绍了如何通过lambda对接口的实现来书写优美的代码。
之后呢,必要的collection知识必须有,附加的还可以了解一下Optional 类、split字符串分割等细节的东西(当然对了解流式编程没有影响),在这些都清楚的情况下,我们可以来进行Java流式编程的学习。
因为我也是学习他人的知识总结,所以对于细节不赘述,只提供链接分享:
https://www.cnblogs.com/shenlanzhizun/p/6027042.html
,这篇文章清晰详细的介绍了几乎所有细节,值得学习,其中我也将代码全部书写了一遍,注释中的东西对于理解也有帮助,现贴出来(实体类不再展示,只展示流式编程的主程序部分)。
public class StreamDemo {
public static void main(String[] args) {
List<Student> students = new ArrayList<Student>() {
{
add(new Student(20160001, "孔明", 20, 1, "土木工程", "武汉大学"));
add(new Student(20160002, "伯约", 21, 2, "信息安全", "武汉大学"));
add(new Student(20160003, "玄德", 22, 3, "经济管理", "武汉大学"));
add(new Student(20160004, "云长", 21, 2, "信息安全", "武汉大学"));
add(new Student(20161001, "翼德", 21, 2, "机械与自动化", "华中科技大学"));
add(new Student(20161002, "元直", 22, 4, "土木工程", "华中科技大学"));
add(new Student(20161003, "奉孝", 23, 4, "计算机科学", "华中科技大学"));
add(new Student(20162001, "仲谋", 22, 3, "土木工程", "浙江大学"));
add(new Student(20162002, "鲁肃", 23, 4, "计算机科学", "浙江大学"));
add(new Student(20163001, "丁奉", 24, 5, "土木工程", "南京大学"));
}
};
/**过滤(筛选:filter,distinct,limit,skip)*/
List<Student> whuStudents = students.stream()
.filter(student -> "武汉大学".equals(student.getSchool()))
.collect(Collectors.toList());
//distinct,独一无二,类似sql
List<Integer> nums=new ArrayList(){
{
add(1);
add(2);
add(2);
}
};
List<Integer> evens = nums.stream()
.filter(num -> num % 2 == 0).distinct()
.collect(Collectors.toList());
System.out.println(evens);
//limit,取前n项,类似sql
List<Student> civilStudents = students.stream()
.filter(student -> "土木工程".equals(student.getMajor())).limit(2)
.collect(Collectors.toList());
System.out.println(civilStudents.get(0).getMajor());
//sorted,实现sorted(Comparator super T> comparator)
List<Student> sortedStudents=students.stream()
.filter(student -> "土木工程".equals(student.getMajor())).sorted(Comparator.comparingInt(Student::getAge))
.limit(2)
.collect(Collectors.toList());
//lambda遍历集合
sortedStudents.forEach(element->{
System.out.println(element.getAge());
});
//skip,与limit相反,跳过前n个元素,找出排序在2之后的
List<Student> civilStudents1 = students.stream()
.filter(student -> "土木工程".equals(student.getMajor()))
.skip(2)
.collect(Collectors.toList());
/**映射(map,flatmap)*/
//map
List<String> names=students.stream()
.filter(student -> "计算机科学".equals(student.getName()))
.map(Student::getName)
.collect(Collectors.toList());
//java8还提供mapToDouble,mapToInt,mapToLong
int totalage=students.stream()
.filter(student -> "计算机科学".equals(student.getMajor()))
.mapToInt(Student::getAge).sum();
//flatMap,了解字符串分割函数spilt(),输出构成这一数组的所有非重复字符
String[] strs={"java8","is","easy","to","use"};
List<String> Distinctstr= Arrays.stream(strs)
.map(str->str.split(""))// 映射成为Stream
.flatMap(Arrays::stream)// 扁平化为Stream
.distinct()
.collect(Collectors.toList());
Distinctstr.forEach(element->{
System.out.print(element);
});
/**终端操作,在终端实现对流的查找、归约等操作*/
/**查找*/
//allMatch(全部)
boolean isAdult=students.stream().allMatch(student -> student.getAge()>=18);
//anyMatch(是否存在一个或多个)
boolean hasWhu=students.stream().anyMatch(student -> "武汉大学".equals(student.getSchool()));
//noneMatch(是否不存在)
boolean noneCs=students.stream().noneMatch(student -> "计算机科学".equals(student.getMajor()));
//findFirst(找到符合条件的第一个元素),了解java8新特性optional类(解决空指针问题)
Optional<Student> optStu=students.stream().filter(student -> "土木工程".equals(student.getMajor()))
.findFirst();
//findAny,返回满足条件的任意一个元素(并式流式,findAny性能优于findFirst)
Optional<Student> optStu1=students.stream().filter(student -> "土木工程".equals(student.getMajor()))
.findAny();
/**归约,不返回集合,而是进行进一步操作,进行上述进行的求和操作*/
//利用reduce方法来达到这一目的
int total=students.stream()
.filter(student -> "计算机科学".equals(student.getMajor()))
.map(Student::getAge)
.reduce(0,(a,b)->a+b);
System.out.println("\n"+total);
// 进一步简化
int totalAge2 = students.stream()
.filter(student -> "计算机科学".equals(student.getMajor()))
.map(Student::getAge)
.reduce(0, Integer::sum);
// 采用无初始值的重载版本,需要注意返回Optional
Optional<Integer> totalAge = students.stream()
.filter(student -> "计算机科学".equals(student.getMajor()))
.map(Student::getAge)
.reduce(Integer::sum); // 去掉初始值
/**收集,toSet,toMap(收集器),大多数操作均有相适应的long和double操作*/
//归约
long count=students.stream().collect(Collectors.counting());
//进一步简化
long count1=students.stream().count();
Optional<Student> olderStudent1=students.stream().collect(Collectors.maxBy((s1,s2)->s1.getAge()-s2.getAge()));
// 进一步简化
Optional<Student> olderStudent2 = students.stream().collect(Collectors.maxBy(Comparator.comparing(Student::getAge)));
// 求最小年龄
Optional<Student> olderStudent3 = students.stream().collect(Collectors.minBy(Comparator.comparing(Student::getAge)));
//求总和
int total3=students.stream().collect(Collectors.summingInt(Student::getAge));
//求平均值
double avgage=students.stream().collect(Collectors.averagingInt(Student::getAge));
System.out.println(avgage);
//一次性得到元素个数、总和、均值、最大值、最小值(了解IntSummaryStatistics)
IntSummaryStatistics statistics=students.stream().collect(Collectors.summarizingInt(Student::getAge));
//字符串拼接
String nameJoin=students.stream().map(Student::getName).collect(Collectors.joining(","));
/**分组,类似数据库操作里面的group by*/
Map<String,List<Student>> groups=students.stream().collect(Collectors.groupingBy(Student::getSchool));
//多级分组
Map<String, Map<String, List<Student>>> groups1 = students.stream().collect(
Collectors.groupingBy(Student::getSchool,Collectors.groupingBy(Student::getMajor)));
System.out.println(groups1.get("浙江大学"));
//第二个参数可以用来统计一些分组信息
Map<String, Long> groups2 = students.stream().collect(Collectors.groupingBy(Student::getSchool, Collectors.counting()));
/**分区*/
//区分是否为武大学生
Map<Boolean, List<Student>> partition = students.stream().collect(Collectors.partitioningBy(student -> "武汉大学".equals(student.getSchool())));
}
}
以上就是Java新特性—流式编程学习笔记代码的分享,我本人也将把流式编程运用到自己平时的项目中,因为很有帮助,为了自己也本着分享的态度,简单写一下这篇博客,最后,再次特别感谢同学在编程方面的无私分享。