我爱Java系列之《JavaEE学习笔记day13》---【lambda表达式】

一.lambda表达式(必须掌握)
    1.函数式编程思想概念
          函数式思想则尽量忽略面向对象的复杂语法——强调做什么,而不是以什么形式做
     2.lambda表达式写法技巧:
         只需要按照匿名内部类的形式写出代码,然后保留抽象方法的()和{},在()和{}之间添加一个->
     3.lambda表达式组成   
        (1)一些参数
         (2)一个箭头
         (3)一段代码

    4.lambda表达式格式:
         (参数列表...)->{代码}

    5.lambda表达式格式解释:
         (1)(参数列表...): 和以前定义方法的参数列表(写在()中)是一致的
             没有参数()留空,有多个参数,用逗号隔开
         (2)->: 代表指向的动作,本质方法参数的传递
         (3){}: 和以前定义方法的{}中是一样的,代表的是方法体的内容

     6.Lambda表达式的省略格式
         (1)数据类型可以省略: (Person p1,Person p2): 省略格式(p1,p2)
         (2)()中只有一个参数,()可以省略: (Perons p): 省略格式(p)   最简化的省略格式: p
         (3)->: 永远不能省略
         (4){}中如果只有一条语句:
             那么{},return,分号 都可以省略
             但是要么全部省略,要么全部保留

     7.lambda表达式的前提
         (1)必须要有接口(函数式接口)
             要求接口中只能有一个(必须要被覆盖重写的)抽象方法,可以有默认方法,可以有静态方法
         (2)必须要有接口作为方法的参数
             @Override:  检测是否是对父类方法的覆盖重写
             @FunctionalInterface: 检测是否是函数式接口

二.常用的函数是接口

   1.消费型接口
         java.util.function.Consumer<T>: 消费型接口
             抽象方法:                                                                        必须掌握
                 public abstract void accept(T t): 消费一个指定泛型T类型的数据
                 注意:

                     什么叫做消费呢?

                因为accept方法是抽象的,只要做覆盖重写{}后,就叫消费了,至于{}中写了哪些代码,我不管


  2.判断型接口   
        java.util.function.Predicate<T>: 判断型接口
             抽象方法:     必须掌握
                 public abstract boolean test(T t): 根据T类型的参数t,返回一个boolean类型的结果

三.Stream流
    1.获取Stream流对象的方法(两种)
        (1)Collection<T>集合
             默认方法:必须由Collection接口的实现类(ArrayList/LinkedList/HashSet/LinkedHashSet)对象调用

            Stream<T> stream()  :获取Collection集合对象的Stream流对象

         代码演示:

  
  
                      //获取List集合的Stream对象
              List<String> list = new ArrayList<>();                                    
                 Stream<String> s1 = list.stream();
                 System.out.println(s1);

                 //获取Set集合的Stream对象
                 Set<Integer> set = new HashSet<>();
                 Stream<Integer> s2 = set.stream();
                 System.out.println(s2);

                 Map<String,String> map = new HashMap<>();

                //Map键的Set集合
                Set<String> set2 = map.keySet();
                Stream<String> s3 = set2.stream();
                System.out.println(s3);

                //Map值的Collection集合
                Collection<String> coll = map.values();
                Stream<String> s4 = coll.stream();
                System.out.println(s4);

               //Map键值对的Set集合
               Set<Map.Entry<String, String>> set3 = map.entrySet();
                Stream<Map.Entry<String, String>> s5 = set3.stream();
               System.out.println(s5);
               System.out.println("----------");
               String[] arr = {"Hello","World","java"};
                Stream<String> s6 = Stream.of(arr);
               System.out.println(s6);

               Stream<String> s7 = Stream.of("Hello", "World", "java");
               System.out.println(s7);

}
}


        
         (2)Stream接口的静态方法

            静态方法
             java.util.stream.Stream<T> 接口:
            public static <T> Stream<T> of(T ... t): 把方法的可变参数指定的具体数据,

              转换成Stream流对象
               参数:
                     T ... t: 可变参数 可以传递数组,参数列表,也可以不传递

                     Stream<String> s = Stream.of("大娃", "二娃", "娃"}                            

     2.Stream流中的forEach方法
         void forEach(Consumer<T> action):  终结方法,调用此方法后,Stream流对象将不可以继续使用

            该方法接收一个Consumer接口函数,会将每一个流元素交给该函数进行处理,不保证顺序

        Consumer接口:
             抽象方法:
                 void accept(T t)
                 s->sout(s);System.out::println

     3.Stream流中的count方法
         long count() : 终结方法,调用此方法后,Stream流对象将不可以继续使用

        返回Stream流对象中的元素的个数,但是返回值类型是long
    4.Stream流中的filter方法
         Stream<T> filter(Predicate<T> predicate) :
             按照方法参数predicate对Stream流对象中的元素进行过滤,并返回新的Stream流对象

        Predicate<T>接口:
             抽象方法:
                 boolean test(T t)

     5.Stream流中的limit方法和skip方法
         Stream<T> limit(long n): 获取流对象中的前n个元素,返回新的Stream流对象
         Stream<T> skip(long n):  跳过流对象中的前n个元素,返回新的Stream流对象
           
    
     6.Stream流中的静态concat方法
        static <T> Stream<T> concat(Stream<T> a, Stream<T> b):
             把两个流对象a和b合并成一个流对象,并返回

四、综合案例

/*
Stream综合案例
1. 第一个队伍只要名字为3个字的成员姓名;
2. 第一个队伍筛选之后只要前3个人;
3. 第二个队伍只要姓张的成员姓名;
4. 第二个队伍筛选之后不要前2个人;
5. 将两个队伍合并为一个队伍;
6. 打印整个队伍的姓名信息。

按照Stream流+匿名内部类的形式
*/

public class Demo02ListEach {
public static void main(String[] args) {
List<String> o = new ArrayList<>();
o.add("迪丽热巴");
o.add("宋远桥");
o.add("苏星河");
o.add("老子");
o.add("庄子");
o.add("孙子");
o.add("洪七公");

//获取第一个队伍的流对象
Stream<String> os1 = o.stream();

//1. 第一个队伍只要名字为3个字的成员姓名;
Stream<String> os2 = os1.filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.length() == 3;
}
});

//2. 第一个队伍筛选之后只要前3个人;
Stream<String> os3 = os2.limit(3);

List<String> t = new ArrayList<>();
t.add("古力娜扎");
t.add("张无忌");
t.add("张三丰");
t.add("赵丽颖");
t.add("张二狗");
t.add("张天爱");
t.add("张三");
//获取第二个队伍的流对象
Stream<String> ts1 = t.stream();

//3. 第二个队伍只要姓张的成员姓名;
Stream<String> ts2 = ts1.filter(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.startsWith("张");
}
});
//4. 第二个队伍筛选之后不要前2个人;
Stream<String> ts3 = ts2.skip(2);

//5. 将两个队伍合并为一个队伍;
Stream<String> ots = Stream.concat(os3, ts3);

//6. 打印整个队伍的姓名信息
ots.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});

}
}

          

/*
Stream综合案例
1. 第一个队伍只要名字为3个字的成员姓名;
2. 第一个队伍筛选之后只要前3个人;
3. 第二个队伍只要姓张的成员姓名;
4. 第二个队伍筛选之后不要前2个人;
5. 将两个队伍合并为一个队伍;
6. 打印整个队伍的姓名信息。

按照Stream流+lambda标准格式的形式(分4步完成)
*/

public class Demo04ListEach {
public static void main(String[] args) {
List<String> o = new ArrayList<>();
o.add("迪丽热巴");
o.add("宋远桥");
o.add("苏星河");
o.add("老子");
o.add("庄子");
o.add("孙子");
o.add("洪七公");

//获取第一个队伍的流对象

//1. 第一个队伍只要名字为3个字的成员姓名;

//2. 第一个队伍筛选之后只要前3个人;
Stream<String> os1 = o.stream().filter(name -> name.length() == 3).limit(3);


List<String> t = new ArrayList<>();
t.add("古力娜扎");
t.add("张无忌");
t.add("张三丰");
t.add("赵丽颖");
t.add("张二狗");
t.add("张天爱");
t.add("张三");
//获取第二个队伍的流对象


//3. 第二个队伍只要姓张的成员姓名;

//4. 第二个队伍筛选之后不要前2个人;

Stream<String> ts1 = t.stream().filter(name -> name.startsWith("张")).skip(2);

//5. 将两个队伍合并为一个队伍;
Stream<String> ots = Stream.concat(os1, ts1);


//6. 打印整个队伍的姓名信息
ots.forEach(name-> System.out.println(name));


}
}

/*
Stream综合案例
1. 第一个队伍只要名字为3个字的成员姓名;
2. 第一个队伍筛选之后只要前3个人;
3. 第二个队伍只要姓张的成员姓名;
4. 第二个队伍筛选之后不要前2个人;
5. 将两个队伍合并为一个队伍;
6. 打印整个队伍的姓名信息。

按照Stream流+lambda标准格式的形式(分1步完成)
*/

public class Demo05ListEach {
public static void main(String[] args) {
List<String> o = new ArrayList<>();
o.add("迪丽热巴");
o.add("宋远桥");
o.add("苏星河");
o.add("老子");
o.add("庄子");
o.add("孙子");
o.add("洪七公");

List<String> t = new ArrayList<>();
t.add("古力娜扎");
t.add("张无忌");
t.add("张三丰");
t.add("赵丽颖");
t.add("张二狗");
t.add("张天爱");
t.add("张三");

//获取第一个队伍的流对象
//1. 第一个队伍只要名字为3个字的成员姓名;
//2. 第一个队伍筛选之后只要前3个人;
//获取第二个队伍的流对象
//3. 第二个队伍只要姓张的成员姓名;
// 4. 第二个队伍筛选之后不要前2个人;
//5. 将两个队伍合并为一个队伍;
//6. 打印整个队伍的姓名信息

Stream.concat(
o.stream().filter(name->name.length()==3).limit(3),
t.stream().filter(name->name.startsWith("张")).skip(2)
).forEach(name-> System.out.println(name));

}
}

猜你喜欢

转载自www.cnblogs.com/hujunwei/p/10793027.html