最新公告
  • 欢迎您光临极客文库,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入我们
  • 简介
    java8 也出来好久了,接口默认方法,lambda 表达式,函数式接口,Date API 等特性还是有必要去了解一下。比如在项目中经常用到集合,遍历集合可以试下 lambda 表达式,经常还要对集合进行过滤和排序,Stream 就派上用场了。用习惯了,不得不说真的很好用。
    Stream 作为 java8 的新特性,基于 lambda 表达式,是对集合对象功能的增强,它专注于对集合对象进行各种高效、便利的聚合操作或者大批量的数据操作,提高了编程效率和代码可读性。
    Stream 的原理:将要处理的元素看做一种流,流在管道中传输,并且可以在管道的节点上处理,包括过滤筛选、去重、排序、聚合等。元素流在管道中经过中间操作的处理,最后由最终操作得到前面处理的结果。
    集合有两种方式生成流:
    • stream() − 为集合创建串行流
    • parallelStream() – 为集合创建并行流
    上图中是 Stream 类的类结构图,里面包含了大部分的中间和终止操作。
    • 中间操作主要有以下方法(此类型方法返回的都是 Stream):map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered
    • 终止操作主要有以下方法:forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator
    举例说明
    首先为了说明 Stream 对对象集合的操作,新建一个 Student 类(学生类), 覆写了 equals() 和 hashCode() 方法
    1. publicclassStudent{
    2. privateLong id;
    3. privateString name;
    4. privateint age;
    5. privateString address;
    6. publicStudent(){}
    7. publicStudent(Long id,String name,int age,String address){
    8. this.id = id;
    9. this.name = name;
    10. this.age = age;
    11. this.address = address;
    12. }
    13. @Override
    14. publicString toString(){
    15. return"Student{"+
    16. "id="+ id +
    17. ", + name + ''' +
    18. ", age=" + age +
    19. ", address='" + address + ''' +
    20. '}';
    21. }
    22. @Override
    23. public boolean equals(Object o) {
    24. if (this == o) return true;
    25. if (o == null || getClass() != o.getClass()) return false;
    26. Student student = (Student) o;
    27. return age == student.age &&
    28. Objects.equals(id, student.id) &&
    29. Objects.equals(name, student.name) &&
    30. Objects.equals(address, student.address);
    31. }
    32. @Override
    33. public int hashCode() {
    34. return Objects.hash(id, name, age, address);
    35. }
    36. public Long getId() {
    37. return id;
    38. }
    39. public void setId(Long id) {
    40. this.id = id;
    41. }
    42. public String getName() {
    43. return name;
    44. }
    45. public void setName(String name) {
    46. this.name = name;
    47. }
    48. public int getAge() {
    49. return age;
    50. }
    51. public void setAge(int age) {
    52. this.age = age;
    53. }
    54. public String getAddress() {
    55. return address;
    56. }
    57. public void setAddress(String address) {
    58. this.address = address;
    59. }
    60. }
    61. 复制代码

    filter(筛选)

    1. publicstaticvoid main(String[] args){
    2. Student s1 =newStudent(1L,"肖战",15,"浙江");
    3. Student s2 =newStudent(2L,"王一博",15,"湖北");
    4. Student s3 =newStudent(3L,"杨紫",17,"北京");
    5. Student s4 =newStudent(4L,"李现",17,"浙江");
    6. List<Student> students =newArrayList<>();
    7. students.add(s1);
    8. students.add(s2);
    9. students.add(s3);
    10. students.add(s4);
    11. List<Student> streamStudents = testFilter(students);
    12. streamStudents.forEach(System.out::println);
    13. }
    14. /**
    15. * 集合的筛选
    16. * @param students
    17. * @return
    18. */
    19. privatestaticList<Student> testFilter(List<Student> students){
    20. //筛选年龄大于15岁的学生
    21. // return students.stream().filter(s -> s.getAge()>15).collect(Collectors.toList());
    22. //筛选住在浙江省的学生
    23. return students.stream().filter(s ->"浙江".equals(s.getAddress())).collect(Collectors.toList());
    24. }
    25. 复制代码
    运行结果:
    这里我们创建了四个学生,经过 filter 的筛选,筛选出地址是浙江的学生集合。

    map(转换)

    1. publicstaticvoid main(String[] args){
    2. Student s1 =newStudent(1L,"肖战",15,"浙江");
    3. Student s2 =newStudent(2L,"王一博",15,"湖北");
    4. Student s3 =newStudent(3L,"杨紫",17,"北京");
    5. Student s4 =newStudent(4L,"李现",17,"浙江");
    6. List<Student> students =newArrayList<>();
    7. students.add(s1);
    8. students.add(s2);
    9. students.add(s3);
    10. students.add(s4);
    11. testMap(students);
    12. }
    13. /**
    14. * 集合转换
    15. * @param students
    16. * @return
    17. */
    18. privatestaticvoid testMap(List<Student> students){
    19. //在地址前面加上部分信息,只获取地址输出
    20. List<String> addresses = students.stream().map(s ->"住址:"+s.getAddress()).collect(Collectors.toList());
    21. addresses.forEach(a ->System.out.println(a));
    22. }
    23. 复制代码
    运行结果
    map 就是将对应的元素按照给定的方法进行转换。

    distinct(去重)

    1. publicstaticvoid main(String[] args){
    2. testDistinct1();
    3. }
    4. /**
    5. * 集合去重(基本类型)
    6. */
    7. privatestaticvoid testDistinct1(){
    8. //简单字符串的去重
    9. List<String> list =Arrays.asList("111","222","333","111","222");
    10. list.stream().distinct().forEach(System.out::println);
    11. }
    12. 复制代码
    运行结果:
    1. publicstaticvoid main(String[] args){
    2. testDistinct2();
    3. }
    4. /**
    5. * 集合去重(引用对象)
    6. */
    7. privatestaticvoid testDistinct2(){
    8. //引用对象的去重,引用对象要实现hashCode和equal方法,否则去重无效
    9. Student s1 =newStudent(1L,"肖战",15,"浙江");
    10. Student s2 =newStudent(2L,"王一博",15,"湖北");
    11. Student s3 =newStudent(3L,"杨紫",17,"北京");
    12. Student s4 =newStudent(4L,"李现",17,"浙江");
    13. Student s5 =newStudent(1L,"肖战",15,"浙江");
    14. List<Student> students =newArrayList<>();
    15. students.add(s1);
    16. students.add(s2);
    17. students.add(s3);
    18. students.add(s4);
    19. students.add(s5);
    20. students.stream().distinct().forEach(System.out::println);
    21. }
    22. 复制代码
    运行结果:
    可以看出,两个重复的 “肖战” 同学进行了去重,这不仅因为使用了 distinct()方法,而且因为 Student 对象重写了 equals 和 hashCode()方法,否则去重是无效的。

    sorted(排序)

    1. publicstaticvoid main(String[] args){
    2. testSort1();
    3. }
    4. /**
    5. * 集合排序(默认排序)
    6. */
    7. privatestaticvoid testSort1(){
    8. List<String> list =Arrays.asList("333","222","111");
    9. list.stream().sorted().forEach(System.out::println);
    10. }
    11. 复制代码
    运行结果:
    1. publicstaticvoid main(String[] args){
    2. testSort2();
    3. }
    4. /**
    5. * 集合排序(指定排序规则)
    6. */
    7. privatestaticvoid testSort2(){
    8. Student s1 =newStudent(1L,"肖战",15,"浙江");
    9. Student s2 =newStudent(2L,"王一博",15,"湖北");
    10. Student s3 =newStudent(3L,"杨紫",17,"北京");
    11. Student s4 =newStudent(4L,"李现",17,"浙江");
    12. List<Student> students =newArrayList<>();
    13. students.add(s1);
    14. students.add(s2);
    15. students.add(s3);
    16. students.add(s4);
    17. students.stream()
    18. .sorted((stu1,stu2)->Long.compare(stu2.getId(), stu1.getId()))
    19. .sorted((stu1,stu2)->Integer.compare(stu2.getAge(),stu1.getAge()))
    20. .forEach(System.out::println);
    21. }
    22. 复制代码
    运行结果:
    上面指定排序规则,先按照学生的 id 进行降序排序,再按照年龄进行降序排序

    limit(限制返回个数)

    1. publicstaticvoid main(String[] args){
    2. testLimit();
    3. }
    4. /**
    5. * 集合limit,返回前几个元素
    6. */
    7. privatestaticvoid testLimit(){
    8. List<String> list =Arrays.asList("333","222","111");
    9. list.stream().limit(2).forEach(System.out::println);
    10. }
    11. 复制代码
    运行结果:

    skip(删除元素)

    1. publicstaticvoid main(String[] args){
    2. testSkip();
    3. }
    4. /**
    5. * 集合skip,删除前n个元素
    6. */
    7. privatestaticvoid testSkip(){
    8. List<String> list =Arrays.asList("333","222","111");
    9. list.stream().skip(2).forEach(System.out::println);
    10. }
    11. 复制代码
    运行结果:

    reduce(聚合)

    1. publicstaticvoid main(String[] args){
    2. testReduce();
    3. }
    4. /**
    5. * 集合reduce,将集合中每个元素聚合成一条数据
    6. */
    7. privatestaticvoid testReduce(){
    8. List<String> list =Arrays.asList("欢","迎","你");
    9. String appendStr = list.stream().reduce("北京",(a,b)-> a+b);
    10. System.out.println(appendStr);
    11. }
    12. 复制代码
    运行结果:

    min(求最小值)

    1. publicstaticvoid main(String[] args){
    2. testMin();
    3. }
    4. /**
    5. * 求集合中元素的最小值
    6. */
    7. privatestaticvoid testMin(){
    8. Student s1 =newStudent(1L,"肖战",14,"浙江");
    9. Student s2 =newStudent(2L,"王一博",15,"湖北");
    10. Student s3 =newStudent(3L,"杨紫",17,"北京");
    11. Student s4 =newStudent(4L,"李现",17,"浙江");
    12. List<Student> students =newArrayList<>();
    13. students.add(s1);
    14. students.add(s2);
    15. students.add(s3);
    16. students.add(s4);
    17. Student minS = students.stream().min((stu1,stu2)->Integer.compare(stu1.getAge(),stu2.getAge())).get();
    18. System.out.println(minS.toString());
    19. }
    20. 复制代码
    运行结果:
    上面是求所有学生中年龄最小的一个,max 同理,求最大值。

    anyMatch/allMatch/noneMatch(匹配)

    1. publicstaticvoid main(String[] args){
    2. testMatch();
    3. }
    4. privatestaticvoid testMatch(){
    5. Student s1 =newStudent(1L,"肖战",15,"浙江");
    6. Student s2 =newStudent(2L,"王一博",15,"湖北");
    7. Student s3 =newStudent(3L,"杨紫",17,"北京");
    8. Student s4 =newStudent(4L,"李现",17,"浙江");
    9. List<Student> students =newArrayList<>();
    10. students.add(s1);
    11. students.add(s2);
    12. students.add(s3);
    13. students.add(s4);
    14. Boolean anyMatch = students.stream().anyMatch(s ->"湖北".equals(s.getAddress()));
    15. if(anyMatch){
    16. System.out.println("有湖北人");
    17. }
    18. Boolean allMatch = students.stream().allMatch(s -> s.getAge()>=15);
    19. if(allMatch){
    20. System.out.println("所有学生都满15周岁");
    21. }
    22. Boolean noneMatch = students.stream().noneMatch(s ->"杨洋".equals(s.getName()));
    23. if(noneMatch){
    24. System.out.println("没有叫杨洋的同学");
    25. }
    26. }
    27. 复制代码
    运行结果
    • anyMatch:Stream 中任意一个元素符合传入的 predicate,返回 true
    • allMatch:Stream 中全部元素符合传入的 predicate,返回 true
    • noneMatch:Stream 中没有一个元素符合传入的 predicate,返回 true
    总结
    上面介绍了 Stream 常用的一些方法,虽然对集合的遍历和操作可以用以前常规的方式,但是当业务逻辑复杂的时候,你会发现代码量很多,可读性很差,明明一行代码解决的事情,你却写了好几行。试试 lambda 表达式,试试 Stream,你会有不一样的体验。
    本站所有文章均由网友分享,仅用于参考学习用,请勿直接转载,如有侵权,请联系网站客服删除相关文章。若由于商用引起版权纠纷,一切责任均由使用者承担
    极客文库 » 高效率!让java8的Stream对集合操作飞起来

    常见问题FAQ

    如果资源链接失效了怎么办?
    本站用户分享的所有资源都有自动备份机制,如果资源链接失效,请联系本站客服QQ:2580505920更新资源地址。
    如果用户分享的资源与描述不符怎么办?
    可以联系客服QQ:2580505920,如果要求合理可以安排退款或者退赞助积分。
    如何分享个人资源获取赞助积分或其他奖励?
    本站用户可以分享自己的资源,但是必须保证资源没有侵权行为。点击个人中心,根据操作填写并上传即可。资源所获收益完全归属上传者,每周可申请提现一次。
    如果您发现了本资源有侵权行为怎么办?
    及时联系客服QQ:2580505920,核实予以删除。

    Leave a Reply

    Hi, 如果你对这款资源有疑问,可以跟我联系哦!

    联系发布者

    Leave a Reply

    Hi, 如果你对这款资源有疑问,可以跟我联系哦!

    联系发布者
    • 102会员总数(位)
    • 3674资源总数(个)
    • 2本周发布(个)
    • 0 今日发布(个)
    • 136稳定运行(天)

    欢迎加入「极客文库」,成为原创作者从这里开始!

    立即加入 了解更多
    成为赞助用户享有更多特权立即升级