Lambda表达式&接口更新&方法引用&函数式接口&Stream流

  • Lambda
    • 1.程序启动三种不同的表现形式
    • 2.Lambda表达式的标准格式
    • 3.练习 Lambda 无参无返回值
    • 4.练习 Lambda 有参无返回值
    • 5.练习 Lambda 有参有返回值
      • 方式1
      • 方式2
    • 6.Lambda 表达式的省略
    • 7.Lambda表达式的注意事项
    • 8.Lambda表达式和匿名内部类的区别
      • 所需类型不同
      • 使用限制不同
      • 实现原理不同
  • 接口更新
    • 接口中的默认方法
    • 接口中的静态方法
    • 接口中的私有方法
    • 具体实现
  • 方法引用
    • 方法引用符
    • 引用类方法
    • 引用对象的实例方法
    • 引用类的实例方法
    • 引用构造器
  • 函数式接口
      • 概述
      • 函数式接口用作方法的参数
      • 函数式接口作为方法的返回值
    • 常用接口
      • 1.Supplier接口
        • test得到数组最大值
      • 2.consumer接口
        • test按要求打印信息
      • 3.Predicate接口
        • test筛选条件
      • 4.Function接口
        • 计算肖猛真实年龄
  • Stream流
    • 体验Stream流
    • Stream流的生成方式
    • 1.Stream流中间操作filter,limit,skip concate,distinct
    • 2.Stream流中间操作sorted()
    • 3.Stream流中间操作map,mapToInt
    • 4.Stream流终结操作forEach,count
    • 6.Stream流的收集操作
    • Stream流综合练习

Lambda

1.程序启动三种不同的表现形式

1.正常静态代理启动

2.匿名内部类启动

3.Lambda表达式启动

package com.xm.lambda;class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println("程序启动---正常静态代理启动");}
}
public class Demo1 {public static void main(String[] args) {//正常启动new Thread(new MyRunnable()).start();//匿名内部类new Thread(new Runnable() {@Overridepublic void run() {System.out.println("程序启动---匿名内部类");}}).start();//无参 lambdanew Thread(()-> System.out.println("程序启动---Lambda")).start();}
}

2.Lambda表达式的标准格式

  • 格式:(形式参数)->{代码块}

  • 形式参数:如果由多个参数,参数之间用逗号隔开,没有参数留空即可

  • ->:固定写法,代表指向动作

  • 代码块:是我们具体要做的事情,也就是以前我们写方法题内容


3.练习 Lambda 无参无返回值

package com.xm.lambda;interface Eat {void eat();
}class EatImpl implements Eat {@Overridepublic void eat() {System.out.println("多吃蔬菜,身体健康----正常代理");}
}public class Demo2 {public static void main(String[] args) {//正常代理Eat e = new EatImpl();e.eat();//匿名内部类new Eat() {@Overridepublic void eat() {System.out.println("多吃蔬菜,身体健康----匿名内部类");}}.eat();//Lambdae = () -> System.out.println("多吃蔬菜,身体健康----匿名内部类");e.eat();}
}

4.练习 Lambda 有参无返回值

package com.xm.lambda;
interface Flyable {void fiy(String s);
}
class FlyableImpl implements Flyable{@Overridepublic void fiy(String s) {System.out.println(s);System.out.println("正常代理");}
}
public class Demo3 {public static void main(String[] args) {//正常代理useFlyable(new FlyableImpl());//匿名内部类useFlyable(new Flyable() {@Overridepublic void fiy(String s) {System.out.println(s);System.out.println("匿名内部类");}});//LambdauseFlyable((String s)->{System.out.println(s);System.out.println("Lambda");});}public static void useFlyable(Flyable f){f.fiy("多吃蔬菜,身体健康!!!!");}
}

5.练习 Lambda 有参有返回值

方式1

与方式2相同

package com.xm.lambda;interface Addable {int add(int x, int y);
}class AddableImpl implements Addable {@Overridepublic int add(int x, int y) {System.out.println("正常代理");return x + y;}
}public class Demo4 {public static void main(String[] args) {//正常代理useAffable(new AddableImpl());//匿名内部类useAffable(new Addable() {@Overridepublic int add(int x, int y) {System.out.println("匿名内部类");return x + y;}});//LambdauseAffable((x, y) -> {System.out.println("Lambda");return x + y;});}public static void useAffable(Addable a) {System.out.println(a.add(20, 30));}
}
方式2

与方式1相同

package com.xm.lambda;interface Addable {int add(int x, int y);
}class AddableImpl implements Addable {@Overridepublic int add(int x, int y) {System.out.println("正常代理");return x + y;}
}public class Demo4 {public static void main(String[] args) {//正常代理System.out.println(new AddableImpl().add(20, 30));//匿名内部类System.out.println(new Addable() {@Overridepublic int add(int x, int y) {System.out.println("匿名内部类");return x + y;}}.add(30, 40));//Lambda 1Addable e = (x, y) -> {System.out.println("Lambda1");return x + y;};System.out.println(e.add(40, 50));//Lambda 2System.out.println(((Addable) (x, y) -> {System.out.println("Lambda2");return x + y;}).add(40, 50));}}

6.Lambda 表达式的省略

  • 参数类型可以省略,在多参的情况下,不能只省略一个
  • 只有一个参数的时候,可以省略小括号
  • 如果代码块的语句只有一条,可以省略大括号和分号,return 语句可以省略

7.Lambda表达式的注意事项

  • 使用Lambda必须有接口,接口中仅有一个抽象方法
  • 必须要有上下文环境,才能推导出Lambda对应的接口
    • 根据局部变量的赋值得知Lambda对应的接口:Runnable r=()->System.out.print(“你好”);
    • 根据调用的方法的参数得知Lambda对应的接口: new Thread()->System.out.println(“你好”).start();
    • 作为返回值为接口类型的返回值

8.Lambda表达式和匿名内部类的区别

所需类型不同
  • 匿名内部类:可以是接口,抽象类,具体类
  • Lambda:只能是接口
使用限制不同
  • 如果接口中有且仅有一个抽象方法,可以用Lambda,或匿名内部类
  • 如果接口中有多于一个抽象方法,只能用匿名内部类
实现原理不同
  • 匿名内部类:编译之后,产生一个单独的.class 字节码文件
  • Lambda:编译之后,没有一个单独的.class字节码文件。对应的字节码会在运行的时候动态生成

接口更新

正常 属性 public static final

正常方法 public abstract

  • 默认方法 Java8
  • 静态方法 Java8
  • 私有方法 Java9

接口中的默认方法

不强制重写,可以重写(去掉default); 接口中可以省略public

接口中的静态方法

不能重写,静态方法只能通过接口名调用,不能通过实现类名或者对象名调用

public可以省略,static不能省略

接口中的私有方法

private void show()

private static void show()

默认方法可以调用私有的静态方法和非静态方法

静态方法只能调用私有的静态方法

具体实现

package com.xm.接口;interface MyInterface {void show1();void show2();default void show3() {System.out.println("show3---接口");}static void show4(){System.out.println("show4---接口中的静态方法只能被接口调用");}default void method1(){System.out.println("method1");show();}default void method2(){System.out.println("method2");show();}private void show(){System.out.println("你好!");System.out.println("你也好!");}static void method3(){System.out.println("method3");showStatic();}private static void showStatic(){System.out.println("你好!");System.out.println("你也好!");}}class MyInterfaceImpl implements MyInterface {@Overridepublic void show1() {System.out.println("show1");}@Overridepublic void show2() {System.out.println("show2");}@Overridepublic void show3() {System.out.println("show3---实现类");}
}public class Demo1 {public static void main(String... args)//可变参数{MyInterface mi= new MyInterfaceImpl();mi.show1();mi.show2();mi.show3();MyInterface.show4();mi.method1();mi.method2();MyInterface.method3();}
}

方法引用

方法引用符

::该符号为引用运算符,它所在的表达式被称为方法引用

  • Lambda 表达式中的参数s 传递给System.out 这个对象调用的println方法去处理
  • 方法引用 直接使用System.out 中的println方法来取代Lambda ,代码更加整洁
package com.xm.方法引用;
interface Printable {void printInt(int x);
}
public class Demo1 {public static void main(String[] args) {usePrintable(i->System.out.println(i));usePrintable(System.out::println);System.out.println(666);((Printable) i->System.out.println(i)).printInt(8888);((Printable)System.out::println).printInt(8888);System.out.println(8888);}public static void usePrintable(Printable p){p.printInt(6666);}
}

引用类方法

实际上是引用类的静态方法

package com.xm.方法引用;interface Converter {int convert(String s);
}public class Demo2 {public static void main(String[] args) {//第一种写法useConverter(s -> Integer.parseInt(s));//省略returnuseConverter(Integer::parseInt);//Lambda表达式被方法引用代替的时候,它的形参全部传递给静态方法parseInt()作为参数
//      第二种写法System.out.println(((Converter) s -> Integer.parseInt(s)).convert("567"));System.out.println(((Converter) Integer::parseInt).convert("567"));}public static void useConverter(Converter c) {int num = c.convert("789");System.out.println(num);}
}

引用对象的实例方法

实际上是通过对象引用类中的成员方法

package com.xm.方法引用;interface Printer {void printUpperCase(String s);
}class PrintString {public void printUpper(String s) {System.out.println(s.toUpperCase());}
}public class Demo3 {public static void main(String[] args) {usePrinter(s -> System.out.println(s.toUpperCase()));PrintString ps = new PrintString();usePrinter(ps::printUpper);//Lambda表的式被对象的实例方法替代的时候,它的形式参数全部传递给该方法作为参数}public static void usePrinter(Printer p) {p.printUpperCase("helloWorld");}
}

引用类的实例方法

实际上是引用类中的成员方法

  • 格式: 类名::成员方法
package com.xm.方法引用;interface MyString {String mySubString(String s, int a, int b);
}public class Demo4 {public static void main(String[] args) {int x = 5;System.out.println(x);useMyString((s, a, b) -> s.substring(a, b));useMyString(String::substring);// 第一个参数作为调用者//后边的参数全部传递给该方法作为参数System.out.println(((MyString) (s, a, b) -> s.substring(a, b)).mySubString("helloWorld!!!", 0, 10));System.out.println(((MyString) (String::substring)).mySubString("helloWorld!!!", 0, 10));}public static void useMyString(MyString m) {String result = m.mySubString("helloWorld!", 0, 5);System.out.println(result);}
}

引用构造器

实际上是引用构造方法

格式:类名::new

举例:Student : : new

package com.xm.方法引用;interface StudentBuilder {Student build(String name, int age);
}class Student {private String name;private int age;public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}public class Demo5 {public static void main(String[] args) {useStudentBuilder(((name, age) -> new Student(name, age)));//引用构造器,Lambda表达式被构造器替代的时候,它的形式参数全部传递给构造器作为参数useStudentBuilder(Student::new);}public static void useStudentBuilder(StudentBuilder sb) {System.out.println(sb.build("肖猛", 18).toString());}
}

函数式接口

概述

函数式接口:有且仅有一个抽象方法的接口(可以有默认,静态,私有方法),是使用Lambda表达式的前提,是Lambda表达式能够顺利推导的前提;

@FunctionalInterface 注解 放在接口上方,若为函数式接口,则编译通过,否则编译失败

@FunctionalInterface 不加不报错,建议加上该注解;

package com.xm.函数式接口;@FunctionalInterface
interface MyInterface {void show();//jdk8default void method() {show1();}//jdk8static void methods() {show1();}//jdk9private static void show1() {System.out.println("static---show1");}
}public class Demo1 {public static void main(String[] args) {//Lambda表达式用做局部变量MyInterface my = () -> System.out.println("你好!");my.show();//回顾接口更新my.method();MyInterface.methods();}
}

函数式接口用作方法的参数

参见方法引用,直接上代码比较直观:

package com.xm.函数式接口;class MyRunnable implements Runnable {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "实现类线程启动");}
}public class Demo2 {public static void main(String[] args) {useRunnable(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "匿名内部类线程启动");}});useRunnable(() -> System.out.println(Thread.currentThread().getName() + "Lambda表达式线程启动"));useRunnable(new MyRunnable());}public static void useRunnable(Runnable r) {new Thread(r).start();}
}

函数式接口作为方法的返回值

即为Lambda表达式作为返回值

本例中的Comparator是函数式接口

return (…) 返回的类型是Comparator 的实现,所以通过return 语句可以推导出Lambda 表达式的写法(实现Comparator 中的抽象方法);

package com.xm.函数式接口;import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;public class Demo3 {public static void main(String[] args) {ArrayList<String> arrayList = new ArrayList<>();arrayList.add("cccc");arrayList.add("aa");arrayList.add("b");arrayList.add("ddd");System.out.println("排序前");System.out.println(arrayList);Collections.sort(arrayList);System.out.println("默认排序");System.out.println(arrayList);Collections.sort(arrayList, getComparator());System.out.println("调用函数式接口作为返回值---按短长排序");System.out.println(arrayList);Collections.sort(arrayList, new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {return o2.length() - o1.length();}});System.out.println("匿名内部类做参数---按长短排序");System.out.println(arrayList);Collections.sort(arrayList, (s1, s2) -> s1.length() - s2.length());System.out.println("Lambda做参数---按短长排序");System.out.println(arrayList);}public static Comparator<String> getComparator() {return (s1, s2) -> s1.length() - s2.length();
//        return new Comparator<String>() {//            public int compare(String s1, String s2) {//                return s1.length() - s2.length();
//            }
//        };}
}

常用接口

Java8在java.uitl.function包下预定义了大量的函数式接口供我们使用;

1.Supplier接口

Supplier:包含一个无参构造方法

  • T get() :获得结果

  • 该方法不需要参数,他会按照某种逻辑(由Lambda表达式实现)返回一个数据

  • Supplier 接口被称为生产型接口,如果我们指定了接口的泛型是什么类型,那么接口中的get方法就会产生什么类型的数据供我们使用

package com.xm.函数式接口;import java.util.function.Supplier;public class Demo4Supplier {public static void main(String[] args) {String s=(getString(() -> "yes"));System.out.println(s);System.out.println((getString(() -> "yes")));System.out.println(getInteger(()->12345));}private static Integer  getInteger(Supplier<Integer> supplier){return supplier.get();}private static String  getString(Supplier<String> supplier){return supplier.get();}
}
test得到数组最大值
package com.xm.函数式接口;import java.util.function.Supplier;public class TestSupplier {public static void main(String[] args) {int [] a= {19, 4, 7, 1, 80, 3};int maxValue = getMax(() -> {int max = a[0];for (int j : a)if (j > max)max = j;return max;});System.out.println(maxValue);}public static Integer getMax(Supplier<Integer> supplier) {return supplier.get();}
}
2.consumer接口

可以作为Lambda表达式或方法引用的赋值目标

表示接受单个输入参数且不返回结果的操作。 与大多数其他功能接口不同, Consumer预计会通过副作用运行。

  • void accept(T t)
    对给定的参数执行此操作。

  • default Consumer andThen(Consumer<? super T> after)
    返回一个组合 Consumer ,它按顺序执行此操作,然后执行 after操作。

  • Consumer接口被称消费型接口,如果我们指定了接口的泛型是什么类型,那么接口中的accept方法就会消费什么类型的数据;

package com.xm.函数式接口;import java.util.function.Consumer;public class Demo5Consumer {public static void main(String[] args) {useConsumer((s) -> System.out.println(s));useConsumer((s) -> System.out.println(new StringBuilder(s).reverse()));((Consumer<String>) (s) -> System.out.println(s)).accept("what");System.out.println("--------------");useConsumer("what",(s)->System.out.println(s),(s)->System.out.println(new StringBuilder(s).reverse()));}public static void useConsumer( String name ,Consumer<String> con,Consumer<String> con2) {con.accept(name);con2.accept(name);System.out.println("-------------");con.andThen(con2).accept(name);}public static void useConsumer(Consumer<String> con) {con.accept("what");}
}
test按要求打印信息
package com.xm.函数式接口;import java.util.function.Consumer;public class TestConsumer {public static void main(String[] args) {String[] strArray = {"肖猛,18", "李玮晴,18", "刘东旭,6"};printConsumer(str -> {String name = str.split(",")[0];System.out.print(name);}, str -> {int age = Integer.parseInt(str.split(",")[1]);System.out.println(age);}, strArray);}//正常情况是这样,因为我用了可变参数,所以strArray 必须是形参的最后一个;
//  printConsumer(strArray,str->{},str->{});
//public static void printConsumer(String... strArray,Consumer<String> con, Consumer<String> con2)    public static void printConsumer(Consumer<String> con, Consumer<String> con2, String... strArray) {for (String str : strArray) {con.andThen(con2).accept(str);} }
}
3.Predicate接口

Predicate接口实际上是谓语匹配

方法:test(T t) 参数T: 输入参数 返回: true如果输入参数与谓词匹配,否则为 false

  • default Predicate and(Predicate<? super T> other)
    返回一个组合谓词,表示此谓词和另一个谓词的短路逻辑AND。

  • static Predicate isEqual(Object targetRef)
    返回一个谓词,根据 Objects.equals(Object, Object)测试两个参数是否相等。

  • default Predicate negate()
    返回表示此谓词的逻辑否定的谓词。

  • default Predicate or(Predicate<? super T> other)
    返回一个组合谓词,表示此谓词与另一个谓词的短路逻辑OR。

  • boolean test(T t)
    根据给定的参数计算此谓词。

package com.xm.函数式接口;import java.util.function.Predicate;public class Demo6Predicate {public static void main(String[] args) {//1.testboolean b1 = checkString("hello", w -> w.length() >= 8);System.out.println(b1);boolean b2 = checkString("helloWorld", w -> w.length() >= 8);System.out.println(b2);//3.and 与boolean b3 = checkString("hello", s -> s.length() > 29, s -> s.equals("hello"));System.out.println(b3);//4.or 或boolean b4 = CheckString("hello", s -> s.length() > 4, s -> s.equals("hello"));System.out.println(b4);}//1.test//判断字符串是否满足条件public static boolean checkString(String s, Predicate<String> predicate) {//        return predicate.test(s);正常判断
//      2.negate(),逻辑非;
//      return !predicate.test(s);return predicate.negate().test(s);}//3.and 与//同一个字符串给出两个不同的判断条件,最后把这两个判断的条件做逻辑与运算的结果作为最终的结果public static boolean checkString(String s, Predicate<String> predicate, Predicate<String> predicate2) {//        boolean b1=predicate.test(s);
//        boolean b2=predicate2.test(s);
//        boolean b=b1&&b2;
//        return b;return predicate.and(predicate2).test(s);}//4.or或public static boolean CheckString(String s, Predicate<String> predicate, Predicate<String> predicate2) {//        boolean b1 = predicate.test(s);
//        boolean b2 = predicate2.test(s);
//        boolean b = b1 || b2;
//        return b;return predicate.or(predicate2).test(s);}}
test筛选条件

条件:年龄字符大于2,年龄大于8的数据放入ArrayList 并遍历

package com.xm.函数式接口;import java.util.ArrayList;
import java.util.function.Predicate;//筛选条件,年龄字符大于2,年龄大于8;的数据放入ArrayList 并遍历
public class TestPredicate {public static void main(String[] args) {String[] strArray = {"肖猛,18", "李玮晴,10", "刘东旭,6"};ArrayList<String> array = new ArrayList<>();Check(strArray, array, s -> s.split(",")[0].length() > 2, s -> Integer.parseInt(s.split(",")[1]) > 8);}public static void Check(String[] strArray, ArrayList<String> array, Predicate<String> predicate, Predicate<String> predicate2) {for (String str : strArray) {if (predicate.and(predicate2).test(str))array.add(str);}for (String string : array)System.out.println(string);}}
4.Function接口

Function(T,R) 表示接受一个参数并生成结果的函数。
这是functional interface,其功能方法是apply(Object) 。

T - 函数输入的类型

R - 函数结果的类型

  • default Function<T,V> andThen(Function<? super R,? extends V> after) 返回首先将此函数应用于其输入的 after函数,然后将 after函数应用于结果。
  • R apply(T t) 将此函数应用于给定的参数。
package com.xm.函数式接口;import java.util.function.Function;public class Demo7Function {public static void main(String[] args) {Integer integer = convert("12345", s -> {dreturn Integer.parseInt(s);});System.out.println("String--->Integer类型:" + integer);
// 有返回值的接口方法,Lambda表达式调用方法,会产生返回值,具体接收看情况而定convertString(2345, i -> {int x = 10000;return String.valueOf(i + x);});String s1 = convertPlus("345", s -> Integer.parseInt(s), i -> String.valueOf(i + 12000));System.out.println("String--->int--->String:" + s1);}//String 类型转化为Integer类型public static Integer convert(String s, Function<String, Integer> f) {return f.apply(s);}//int 类型加一个整数,转化为String类型public static void convertString(int i, Function<Integer, String> f) {String s = f.apply(i);System.out.println("Integer--->字符串类型:" + s);}//把一个字符串转化为int 类型,加上一个整数后,转为字符串输出public static String convertPlus(String s, Function<String, Integer> f, Function<Integer, String> f2) {//        int i=f.apply(s);
//        String ss=f2.apply(i);
//        return ss;return f.andThen(f2).apply(s);}
}
计算肖猛真实年龄

假设:String s=“肖猛,20”;

要求:

  1. 将字符串截取,得到数字年龄部分
  2. 将数字年龄部分转化为int类型的数据
  3. 将上部int型的年龄减去2,得到一个int结果就是肖猛真实年龄,在控制台输出
package com.xm.函数式接口;import java.util.function.Function;public class TestFunction {public static void main(String[] args) {System.out.println("盲猜肖猛年龄为20");int answer = convertFunction("肖猛,20", s -> Integer.parseInt(s.split(",")[1]) - 2);System.out.println("肖猛的真实年龄:" + answer);}public static int convertFunction(String s, Function<String, Integer> f) {return f.apply(s);}
}

Stream流

体验Stream流

Stream 流把真正的函数式编程风格引入Java中

筛选学生

package com.xm.Stream流;import java.util.ArrayList;public class Demo1 {public static void main(String[] args) {ArrayList<String> array = new ArrayList<>();ArrayList<String> array1 = new ArrayList<>();ArrayList<String> array2 = new ArrayList<>();array.add("肖猛");array.add("肖限量");array.add("李肥肥");array.add("肖扬1");for (String name : array) {if (name.charAt(0) == '肖') {array1.add(name);if (name.length() == 3)array2.add(name);}}for (String name3 : array2)System.out.println(name3);System.out.println("-----------");
//        array.stream().filter(s -> s.startsWith("肖")).filter(s -> s.length() == 3).forEach(System.out::println);array.stream().filter(s -> s.startsWith("肖")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s));}
}

Stream流的生成方式

  1. Collection 体系(Set,List的集合可以使用默认方法stream() 生成流
  2. Map体系的集合间接的生成流
  3. 数组可以通过Stream 接口的静态方法of (T … values)生成流
package com.xm.Stream流;import java.util.*;
import java.util.stream.Stream;public class Demo2 {public static void main(String[] args) {//1.Collection 体系(Set,List的集合可以使用默认方法Stream() 生成流ArrayList<String> arrayList=new ArrayList<>();arrayList.add("1");arrayList.add("12");arrayList.add("123");arrayList.add("1234");arrayList.add("12345");arrayList.add("123456");Stream<String> arrayStream = arrayList.stream();//2.Map体系的集合间接的生成流Map<String,Integer> map=new HashMap<>();//键的Stream流Stream<String> keyStream = map.keySet().stream();//值的Stream流Stream<Integer> valueStream = map.values().stream();//键值对的Stream流Stream<Map.Entry<String, Integer>> mapStream = map.entrySet().stream();// 数组的Stream流String []str={"你好","你也好","都挺好"};Stream<String> strStream = Stream.of(str);Stream<Integer> integerStream = Stream.of(10, 20, 30);}
}

1.Stream流中间操作filter,limit,skip concate,distinct

Streamfilter (Predicate predicate):用于对流中的数据进行过滤

Predicate 接口中的方法 boolean test(T t) :对给定的参数进行判断,返回布尔值;

Stream limit(long maxSize) :返回此流中的元素组成的流,截取前指定参数个数的数据

Streamskip(long n):跳过指定个数的数据,返回有该流的剩余元素组成的流

staticStreamconcat(Stream a,Stream b):合并a和b两个流为一个流

StreamDistinct():返回由该流的不同元素(根据Object.equals(Object))组成的流 底层实现:equal方法;

package com.xm.Stream流;import java.util.ArrayList;
import java.util.stream.Stream;public class Demo3 {public static void main(String[] args) {ArrayList<String> array = new ArrayList<>();array.add("肖彦斌");array.add("肖限量");array.add("李肥肥");array.add("肖扬1");array.add("肖志强");//filter    过滤array.stream().filter(s->s.startsWith("肖")).filter(s -> s.length()==3).forEach(s->System.out.println(s));System.out.println("-------");//limit   返回前N 个数据组成的流Stream<String> limit = array.stream().limit(3);array.stream().limit(3).forEach(System.out::println);System.out.println("-------");//skip 跳过 前N个数据,返回 剩余数据组成的流Stream<String> skip = array.stream().skip(2);array.stream().skip(2).forEach(System.out::println);System.out.println("-------");//concat Stream流合并
//        Stream.concat(limit,skip).forEach(System.out::println);
//        Stream.concat(array.stream().limit(3),array.stream().skip(2)).forEach(System.out::println);//distinct 返回由该流的不同元素(根据Object.equals(Object))组成的流 底层实现:equal方法;System.out.println("what");Stream.concat(limit,skip).distinct().forEach(System.out::println);}
}

2.Stream流中间操作sorted()

Streamsorted():返回由此流的元素组成的流,根据自然顺序排序

Streamstored(Comparator comparator):返回由该流的元素组成的流,根据提供的Comparator进行排序

package com.xm.Stream流;import java.util.ArrayList;
import java.util.Collections;public class Demo4 {public static void main(String[] args) {ArrayList<String > list=new ArrayList<>();list.add("bbb");list.add("aaaa");list.add("aaac");list.add("aaab");list.add("c");Collections.sort(list);Collections.sort(list,(s1,s2)->s1.length()-s2.length());for(String s:list)System.out.println(s);list.stream().sorted().forEach(System.out::println);list.stream().sorted((s1,s2)->s1.length()-s2.length()).forEach(System.out::println);list.stream().sorted((s1,s2)->{int num1=s1.length()-s2.length();return num1==0?s1.compareTo(s2):num1;}).forEach(System.out::println);}
}

3.Stream流中间操作map,mapToInt

Streammap(Function mapper) :返回由给定函数应用于此流的元素的结果组成的流 Function 接口中的方法 R apply(T t);

IntStream mapToInt (ToIntFunction mapper):返回一个IntStream其中包含将给定函数应用于此流的元素的结果。

package com.xm.Stream流;import java.util.ArrayList;
import java.util.stream.IntStream;public class Demo5 {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("10");list.add("20");list.add("30");list.add("40");//map   将字符串数据转化为整数之后在控制台输出list.stream().map(Integer::parseInt).forEach(System.out::println);//list.stream().map(s -> Integer.parseInt(s)).forEach(s->System.out.println(s));//mapToInt// sum方法返回 IntStream 中的数值总和;IntStream intStream = list.stream().mapToInt(Integer::parseInt);int sum = intStream.sum();System.out.println(sum);}
}

4.Stream流终结操作forEach,count

void ForEach(Consumer action):对此流的每一个元素执行操作 Consumer接口中的方法 void accept(T t):对给定的参数执行此操作

long count() :返回此流中的元素个数

package com.xm.Stream流;import java.util.ArrayList;public class Demo5 {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("10");list.add("20");list.add("30");list.add("40");// forEachlist.stream().forEach(System.out::println);//countlong count = list.stream().count();System.out.println(count);

6.Stream流的收集操作

  • R collect(Collector collector) 该收集方法的参数是一个Collector接口

工具类Collectors提供了具体的收集方式

  • public static Collector toList():把元素收集到List集合中
  • public static Collector toSet():把元素收集到Set集合中
  • public static Collector toMap(Function keyMapper,Function valueMapper):把元素收集到Map集合
package com.xm.Stream流;import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;public class Demo7 {public static void main(String[] args) {ArrayList<String> arrayList = new ArrayList<>();arrayList.add("李肥肥");arrayList.add("肖一");arrayList.add("动见");arrayList.add("曾国藩");arrayList.add("左宗棠");List<String> list = arrayList.stream().filter(s -> s.length() == 3).collect(Collectors.toList());for (String s : list)System.out.println(s);Set<Integer> hashSet = new HashSet<>();hashSet.add(10);hashSet.add(20);hashSet.add(30);hashSet.add(40);hashSet.add(50);hashSet.add(6000_000);Set<Integer> set = hashSet.stream().filter(s -> s >= 40).collect(Collectors.toSet());for (Integer i : set)System.out.println(i);String[] str = {"肖猛,18", "李肥肥,18", "刘东旭,8", "小透明,7"};Stream<String> strStream = Stream.of(str).filter(s -> Integer.parseInt(s.split(",")[1]) > 10);Map<String, Integer> map = strStream.collect(Collectors.toMap(s -> s.split(",")[0], s -> Integer.parseInt(s.split(",")[1])));//遍历1Set<Map.Entry<String, Integer>> entries = map.entrySet();for (Map.Entry<String, Integer> element : entries) {System.out.println(element.getKey() + element.getValue());}System.out.println("-----------------");//遍历2Set<String> keySet = map.keySet();for(String key:keySet) {System.out.println(key+map.get(key));}}
}

Stream流综合练习

现在要有ArrayList集合,分别储存5名男生和5名女生,要求完成如下的操作

男生只要名字为3个字的前3人

女生只要姓林的,并且不要第一个

把过滤后的男生姓名和女生姓名合并到一起

把上一步操作后的元素作为构造方法的参数创建性别对象,遍历数据Person类已经提供,里面有一个成员变量,一个带参构造方法,已经成员变量对应的get/set方法

package com.xm.Stream流;import java.util.ArrayList;
import java.util.stream.Stream;public class Demo6 {public static void main(String[] args) {ArrayList<String>  boyList=new ArrayList<>();boyList.add("李肥肥");boyList.add("肖一");boyList.add("动见");boyList.add("曾国藩");boyList.add("左宗棠");ArrayList<String> girlList=new ArrayList<>();girlList.add("窦漪房");girlList.add("肖涵");girlList.add("武则天");girlList.add("肖允许");girlList.add("小透明");ArrayList<Person> peopleList=new ArrayList<>();Stream<String> boy = boyList.stream().filter(s -> s.length() == 3).limit(3);Stream<String> girl=girlList.stream().filter(s->s.startsWith("肖")).skip(1);//先把肖挑选出来组成新流,再从中跳过第一个;
//        Stream.concat(boy,girl).forEach(s-> peopleList.add(new Person(s)));
//        for(Person person:peopleList)
//            System.out.println(person);Stream<String> stream = Stream.concat(boy, girl);Stream<Person> personStream = stream.map(s -> new Person(s));personStream.forEach(System.out::println);}
}
class Person{private String name;public Person(String name) {this.name = name;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +'}';}public Person(){}
}

Lambda表达式接口更新方法引用函数式接口Stream流相关推荐

  1. 十三、Java高级特性 Lambda表达式 | 接口组成更新 | 方法引用 | 函数式接口

    文章目录 十三.Java高级特性 1.Lambda表达式 1.1体验Lambda表达式[理解] 1.2Lambda表达式的标准格式[理解] 1.3Lambda表达式练习1[应用] 1.4Lambda表 ...

  2. java8新特性lambda表达式、函数式编程、方法引用和接口默认方法以及内部类访问外部变量

    一提到java是一种什么语言? 大多数人肯定异口同声的说是一门面向对象的语言,这种观点从我们开始学java就已经根深蒂固了,但是学到java8新特性函数式编程的时候,我才知道java并不是纯面向对象的 ...

  3. 函数式接口、方法引用

    概念 函数式接口在Java中是指:有且仅有一个抽象方法的接口. 函数式接口,即适用于函数式编程场景的接口.而Java中的函数式编程体现就是Lambda,所以函数式接口就是可以适用于Lambda使用的接 ...

  4. Java8新特性学习_001_(Lambda表达式,函数式接口,方法引用,Stream类,Optional类)

    目录 ■代码 ■代码运行结果 ■代码说明 ・44行:Stream的.foreach方法ー参数类型:函数式接口 ・82行:Interface中,default方法 ・92行   Stream的.max方 ...

  5. 函数式编程-Stream流/lambda表达式/Optional/函数式接口/方法引用/高级用法

    函数式编程-Stream流 不会Lambda表达式.函数式编程?你确定能看懂公司代码?-java8函数式编程(Lambda表达式,Optional,Stream流)从入门到精通-最通俗易懂 1. 概述 ...

  6. Java23-day14【函数式接口(Supplier\Consumer\Predicate\Function)、Stream流(生产方式\中间方法\终结方法)】

    视频+资料[链接:https://pan.baidu.com/s/1MdFNUADVSFf-lVw3SJRvtg   提取码:zjxs] Java基础--学习笔记(零起点打开java世界的大门)--博 ...

  7. 表达式类型的实现_程序员如何使代码简洁,Lambda表达式入门之四大引用(下篇)...

    享学课堂特邀作者:老顾转载请声明出处! 前言 上一篇介绍了lambda表达式的语法,今天老顾继续介绍 Lambda类型 Lambda表达式可以被当做是一个Object.Lambda表达式的类型,叫做& ...

  8. 【JavaSE】JDK新特性(二)————接口新特性,函数式接口(Suppier,Comsumer,Predicate,Function)

    文章目录 1.接口新特性 1.1 接口组成更新概述 1.2 接口中的默认方法 1.3 接口中的静态方法 1.4 接口中的私有方法 2. 函数式接口 2.1 函数式接口概述 2.2 函数式接口作为方法的 ...

  9. java socket接口文档_Java进阶 - 网络编程、Socket、函数式接口、常用的函数式接口...

    1.网络通信协议 网络通信协议:通信协议是对计算机必须遵守的规则,只有遵守这些规则,计算机之间才能进行通信.这就好比在道路中行驶的汽车一定要遵守交通规则一样,协议中对数据的传输格式.传输速率.传输步骤 ...

最新文章

  1. 360度无死角、近距离看「CNN」训练,是种什么体验?网友:美得不真实
  2. JavaScript的基础
  3. 机房收费--上机状态查询
  4. Windows服务器上Mysql为设置允许远程连接提示:not allowed to connect to this MySQL server
  5. mybatis.net mysql_ADO.NET与ORM的比较(5):MyBatis实现CRUD
  6. 全国计算机等级考试题库二级C操作题100套(第02套)
  7. 大小不固定的图片、多行文字的水平垂直居中
  8. 笨办法学 Python · 续 练习 6:`find`
  9. sql语句分析是否走索引_SQL语句无法走索引的一些情况分析及语句改写思路
  10. 转转参数信息服务器,转转登录服务器异常
  11. 登顶 GitHub 趋势榜,标星1.8k:200 行 JS 代码让画面人物瞬间消失!
  12. 心理学家发现脚部动作可表现性格特征
  13. 美国发布“几乎无法入侵”的国家量子互联网蓝图,计划十年内出原型
  14. 多媒体计算机技术未来的发展方向,多媒体技术的发展现状及未来
  15. 用nodejs和vue实现消息盒子
  16. 用python解决放苹果问题_放苹果
  17. 怎么理解毕业论文中理论意义和实践意义的区别?
  18. 数据可视化学习(一)——折线图和散点图
  19. PacBio三代测序专业术语解读
  20. oracle重命名表空间

热门文章

  1. base64stego--即base64隐写
  2. windows下安装python+scrapy
  3. ctfshow文件上传
  4. Unsupervised Deep Anomaly Detection for Multi-Sensor Time-Series Signals-TKDE-A类-
  5. 解决Mysql错误1040 Too many connections的方法
  6. Android 开发中 adb remount命令的作用是什么?
  7. Java开发微信公众平台之浅谈微信(一)
  8. PTA 7-116 点与圆的位置关系
  9. UVCCamera实现USB摄像头Android的APP
  10. 瀑布流/媒体查询/栅格化布局/导航条