zoukankan      html  css  js  c++  java
  • JAVA8给我带了什么——流(入门)

    JAVA8有一个新功能——流。笔者简单的看一下流。然后默默的闭上眼睛。感叹一声:这不是.NET里面的Linq吗?如果你们当中有谁做过.NET程序员的话,对于流的学习其实帮助是很大的。但是要明白你现在是在学JAVA的流。虽然他们的概念是有一点像。可是这也只是对你在理解流上面有一定的帮助。因为JAVA实现的方式却完成不一样子(不入流程序员的个人理解)。

    好吧。那么流是什么呢?如果用书里面的方式解释的话,笔者可能也看不懂。做过开发的人员一般都会知道一些SQL语句吧,SELECT语句这个功能。相信大家一定都熟悉吧——SELECT是对数据库的数据进行操作。同样子JAVA也有数据啊。比如集合、数组。那么为什么JAVA不可能实现一套代码式的数据操作。如果这样子不知道大家会不会明白呢?(当然这不是官方,是不入流的程序员这样了理解的)
    SQL语句里面有什么——SELECT、FORM、WHERE、ORDER BY、GROUP BY。这些都是对数据库里面数据操作的常规动作。JAVA8的流呢? 即然是流。那么说明必须把对应的数据变成一个流才行。关键方法stream()就是这个作用。 举例子来说明吧。笔者有一组字符数组,笔者相要查找出有含有 r 的字符。

     1 package com.aomi;
     2 
     3 import java.util.Arrays;
     4 import java.util.List;
     5 
     6 public class Main {
     7 
     8     public static void main(String[] args) {
     9         // TODO Auto-generated method stub
    10 
    11         List<String> datas = Arrays.asList("red", "green", "bule");
    12 
    13         datas
    14         .stream()
    15         .filter(s -> s.contains("r"))
    16         .forEach(s -> System.out.println(s));
    17     }
    18 
    19 }

    运行结果:

    让我们想想如果是以前的话,要什么样子去实现呢?

     1 package com.aomi;
     2 
     3 import java.util.ArrayList;
     4 import java.util.Arrays;
     5 import java.util.List;
     6 
     7 public class Main {
     8 
     9     public static void main(String[] args) {
    10         // TODO Auto-generated method stub
    11 
    12         List<String> datas = Arrays.asList("red", "green", "bule");
    13 
    14 //        datas
    15 //        .stream()
    16 //        .filter(s -> s.contains("r"))
    17 //        .forEach(s -> System.out.println(s));
    18 
    19         List<String> vDatas = new ArrayList<>();
    20 
    21         for (String str : datas) {
    22             if (str.contains("r")) {
    23                 vDatas.add(str);
    24             }
    25         }
    26 
    27         for (String str : vDatas) {
    28             System.out.println(str);
    29         }
    30 
    31     }
    32 
    33 }

    相对以前来讲很直观表现代码的意思。同时代码量又小很多。

    • filter:用于过滤数据的,从下面的代码就可以明白,返回一个boolean型类的结果。
    Stream<T> filter(Predicate<? super T> predicate);
    • forEach:循环遍历回来的结果集合。代码看完就知道什么样子用了。
     void forEach(Consumer<? super T> action);

    JAVA的代很多都是很人性化的,所以只要从名字就可以明白他大概的功能了。

    好了,笔者突然有一个想法——想要把时面的‘r’字符变成‘o’字符。

     1 package com.aomi;
     2 
     3 import java.util.Arrays;
     4 import java.util.List;
     5 
     6 public class Main {
     7 
     8     public static void main(String[] args) {
     9         // TODO Auto-generated method stub
    10 
    11         List<String> datas = Arrays.asList("red", "green", "bule");
    12 
    13         datas.stream()
    14         .map(s -> s.replace('r', 'o'))
    15         .forEach(s -> System.out.println(s));
    16 
    17     }
    18 
    19 }

    笔者去掉了filter方法,用了map。运行结果:

    • map:相当于SQL中的 SELECT关键字有一点像。用于把结果变成你希望的样子。看一下代码
     <R> Stream<R> map(Function<? super T, ? extends R> mapper);

    是一个function的函数式接口。函数描述符:T -> R。
    显示这样子的例子有一点简单。在实际的开发过程中我们往往都是一大波数据对象。这样子笔者定义一个学生类。

    package com.aomi;
    
    public class Student {
        private String name;
        private int Sex;
        private String phone;
        private int score;
        
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getSex() {
            return Sex;
        }
        public void setSex(int sex) {
            Sex = sex;
        }
        public String getPhone() {
            return phone;
        }
        public void setPhone(String phone) {
            this.phone = phone;
        }
        public int getScore() {
            return score;
        }
        public void setScore(int score) {
            this.score = score;
        }
        
        
    }

    在来写一个数据源吧。

     1 package com.aomi;
     2 
     3 import java.util.ArrayList;
     4 import java.util.Arrays;
     5 import java.util.List;
     6 
     7 public class Main {
     8 
     9     public static List<Student> getSources()
    10     {
    11         List<Student> students =new ArrayList<>();
    12         
    13         Student stu1 = new Student();
    14         
    15         stu1.setName("lucy");
    16         stu1.setSex(0);
    17         stu1.setPhone("13700227892");
    18         stu1.setScore(9);
    19         
    20         Student stu2 = new Student();
    21         stu2.setName("lin");
    22         stu2.setSex(1);
    23         stu2.setPhone("15700227122");
    24         stu2.setScore(9);
    25         
    26         Student stu3 = new Student();
    27         stu3.setName("lili");
    28         stu3.setSex(0);
    29         stu3.setPhone("18500227892");
    30         stu3.setScore(8);
    31         
    32         Student stu4 = new Student();
    33         
    34         stu4.setName("dark");
    35         stu4.setSex(1);
    36         stu4.setPhone("16700555892");
    37         stu4.setScore(6);
    38         
    39         
    40         students.add(stu1);
    41         students.add(stu2);
    42         students.add(stu3);
    43         students.add(stu4);
    44         
    45         return students;
    46     }
    47 
    48 }

    笔者定义了四个学生。这样子时候笔者想看看学分(Score)大于6同学的名字有哪一些。从上面代码我们可以看到除了第四个同学drak之后,其他都是合格的。 让我们看一下代码

     1 package com.aomi;
     2 
     3 import java.util.ArrayList;
     4 import java.util.List;
     5 import static java.util.stream.Collectors.toList;
     6 
     7 public class Main {
     8 
     9     public static void main(String[] args) {
    10         // TODO Auto-generated method stub
    11 
    12         List<Student> stus = getSources();
    13 
    14         List<String> names = stus.stream()
    15                 .filter(stu -> stu.getScore() > 6)
    16                 .map(stu -> stu.getName())
    17                 .collect(toList());
    18 
    19         for (String name : names) {
    20             System.out.println(name);
    21         }
    22 
    23     }
    24 
    25     public static List<Student> getSources() {
    26         List<Student> students = new ArrayList<>();
    27 
    28         Student stu1 = new Student();
    29 
    30         stu1.setName("lucy");
    31         stu1.setSex(0);
    32         stu1.setPhone("13700227892");
    33         stu1.setScore(9);
    34 
    35         Student stu2 = new Student();
    36         stu2.setName("lin");
    37         stu2.setSex(1);
    38         stu2.setPhone("15700227122");
    39         stu2.setScore(9);
    40 
    41         Student stu3 = new Student();
    42         stu3.setName("lili");
    43         stu3.setSex(0);
    44         stu3.setPhone("18500227892");
    45         stu3.setScore(8);
    46 
    47         Student stu4 = new Student();
    48 
    49         stu4.setName("dark");
    50         stu4.setSex(1);
    51         stu4.setPhone("16700555892");
    52         stu4.setScore(6);
    53 
    54         students.add(stu1);
    55         students.add(stu2);
    56         students.add(stu3);
    57         students.add(stu4);
    58 
    59         return students;
    60     }
    61 
    62 }

    运行结果:

    当我们看到这个例子的时候,我们就可以确定map是做什么。就是用于最后确定返回数据类型。在这个代码中。笔者又用到了一个叫collect的方法。

    • collect:用于收集数据的功能。即是把相关的数据汇总成为另一种数据。

    笔者传入是toList()方法。把最后数据变成一个集合。这个方法是Collectors类的一个静态方法。当然Collectors类里面有很多静态方法。如果你们去看一下他的代码。你就会发现他的方法名字好像都是在对数据操作的样子。没有错。以后我们开发过程都会用到Collectors类的方法集。
    记得引用下面代码

    import static java.util.stream.Collectors.toList;

     从上面的几个例子来看。让笔者感觉如下

    • stream相关于SQL里面的FROM
    • filter相当于SQL里面的WHERE.
    • map相当于SQL里面的SELECT

    那么其他呢?比如 order by或 group by 。让我们接着看吧。

    现在笔者想在按学分(Score)高到低排序并且只显示学生名和学分呢?

    package com.aomi;
    
    import static java.util.Comparator.comparing;
    import static java.util.stream.Collectors.toList;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class SMain {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
    
            List<Student> stus = getSources();
    
            List<String> names = stus.stream()
                    .sorted(comparing(Student::getScore).reversed())
                    .map(stu -> "学名:"+stu.getName()+"  学分:"+stu.getScore())
                    .collect(toList());
    
            
            for (String name : names) {
                System.out.println(name);
            }
    
        }
    
        public static List<Student> getSources() {
            List<Student> students = new ArrayList<>();
    
            Student stu1 = new Student();
    
            stu1.setName("lucy");
            stu1.setSex(0);
            stu1.setPhone("13700227892");
            stu1.setScore(9);
    
            Student stu2 = new Student();
            stu2.setName("lin");
            stu2.setSex(1);
            stu2.setPhone("15700227122");
            stu2.setScore(9);
    
            Student stu3 = new Student();
            stu3.setName("lili");
            stu3.setSex(0);
            stu3.setPhone("18500227892");
            stu3.setScore(8);
    
            Student stu4 = new Student();
    
            stu4.setName("dark");
            stu4.setSex(1);
            stu4.setPhone("16700555892");
            stu4.setScore(6);
    
            students.add(stu1);
            students.add(stu2);
            students.add(stu3);
            students.add(stu4);
    
            return students;
        }
    }

    运行结果:

    关于上面sorted的用法。笔者上面已经讲过了。
    现在笔者想看看男女各位的学习情况。又要如何。来分个组吧。

     1 package com.aomi;
     2 
     3 import static java.util.stream.Collectors.groupingBy;
     4 
     5 import java.util.ArrayList;
     6 import java.util.List;
     7 
     8 public class SMain {
     9 
    10     public static void main(String[] args) {
    11         // TODO Auto-generated method stub
    12 
    13         List<Student> stus = getSources();
    14 
    15         stus.stream()
    16         .collect(groupingBy(ss -> ss.getSex())).
    17         forEach((Integer sex, List<Student> students) -> {
    18             System.out.println("sex:" + sex);
    19 
    20             for (Student student : students) {
    21                 System.out.println("name:" + student.getName() + "  score:" + student.getScore());
    22             }
    23         });
    24 
    25     }
    26 
    27 //去掉学生源的方法。太多了影响查看
    28 }

    结果:

    即然都分组了。那就笔者在做一个业务。查看男女个组的人数。

    package com.aomi;
    
    import static java.util.stream.Collectors.groupingBy;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.stream.Collectors;
    
    public class SMain {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
    
            List<Student> stus = getSources();
    
            stus.stream().collect(groupingBy(ss -> {
                if (ss.getSex() == 0)
                    return "女";
                else
                    return "男";
            }, Collectors.counting()))
            .forEach((String sex, Long count) -> {
                System.out.println("sex:" + sex + "  count:" + count);
    
            });
    
        }
    ......
    .....//去掉数据源
    .....
    
    }

    运行结果:

    在来一个分组之后,男女个组的总分。

    package com.aomi;
    
    import static java.util.stream.Collectors.groupingBy;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.stream.Collectors;
    
    public class SMain {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
    
            List<Student> stus = getSources();
    
            stus.stream().collect(groupingBy(ss -> {
                if (ss.getSex() == 0)
                    return "女";
                else
                    return "男";
            }, Collectors.summingLong(t -> t.getScore())))
            .forEach((String sex, Long sum) -> {
                System.out.println("sex:" + sex + "  count:" + sum);
    
            });
    
        }
    
        。。。。。
    }

    运行结果:

    通过这俩个例子,我们就可以明白一个道理。groupingBy的第二个参数,是一个任何型类的收集器。也就是说分组之后,你可以在进行对分组之后的结果进处理。

    好了。你们有没有感觉跟SQL语句的功能很像呢?如下

    • stream相关于SQL里面的FROM
    • filter相当于SQL里面的WHERE.
    • map相当于SQL里面的SELECT
    • sorted相当于SQL里面的Order BY
    • Collectors.groupingBy相当于SQL里面的GROUP BY
    • Collectors.summingLong相当于SQL里面的SUM函数。只不过他又加了一步结果转为Long类型
    • Collectors.counting相当于SQL里面的COUNT函数

     理解了上面代码的基础用法的概念之后,我们接下要一步步去看看JAVA8流的思想。

  • 相关阅读:
    搭建 Linux 下 GitLab 服务器(转)
    sql语法:inner join on, left join on, right join on具体用法
    Android Studio之同一应用创建多个Activity(一)
    java环境变量配置
    老鸟的Python新手教程
    域名注冊以及域名解析设置
    Android在WebView上构建Web应用程序
    利用JasperReport+iReport进行Web报表开发
    android App Widgets
    多数据库下activiti的流程定义缓存问题
  • 原文地址:https://www.cnblogs.com/hayasi/p/10623021.html
Copyright © 2011-2022 走看看