什么是函数式编程?
是一种编程模型,把计算机中的运算看做数学中的函数计算,并且避免了状态及变量的概念 f(x)
函数式接口
第一种:就是在一个接口中定义唯一的一个抽象方法,那么这个接口就是函数式接口
public interface FunctionInterfaceDemo { void sayHello(); }
第二种:通过注解的方式@FunctionalInterface声明,加注解相当于加了一个强制性的约束
@FunctionalInterface public interface FunctionInterfaceDemo { void sayHello(); }
函数式接口里面也可以有实现方法,好处是修改接口后不需要改实现,使得接口在发布之后仍然可以升级
@FunctionalInterface public interface FunctionInterfaceDemo { void sayHello(); //java8两种实现方法方式 static void sayHi(){ System.out.println("say hi"); } default void doAnything(){ System.out.println("do anything"); } }
public class Main { public static void main(String[] args) { FunctionInterfaceDemo fi = new FunctionInterfaceDemo() { @Override public void sayHello() { System.out.println("say hello"); } }; fi.sayHello(); fi.doAnything(); FunctionInterfaceDemo.sayHi(); } }
重写父类的方法不违背函数式接口的定义
例如重写equals或toString
@FunctionalInterface public interface FunctionInterfaceDemo { void sayHello(); //java8两种实现方法方式 static void sayHi(){ System.out.println("say hi"); } default void doAnything(){ System.out.println("do anything"); } boolean equals(Object object); }
Lambda表达式
语法组成:
1. 一个括号内用逗号分隔的形式参数,参数是
函数式接口里面的方法参数
2. 一个箭头号 ->
3. 方法体或者代码块
(parameters) -> expression
public class MainDemo2 { public static void main(String[] args) { //传统方式启动一个线程 new Thread(new Runnable() { @Override public void run() { System.out.println("I am thread test1"); } }).start(); //Lambda简化后 new Thread(()->{ System.out.println("I am thread test2"); }).start(); //Lambda继续简化,整个代码块只有一行代码,而这一行代码就是表达式的返回值的话就可以省略代码块 new Thread(()-> System.out.println("I am thread test3")).start(); } }
public class MainDemo3 { public static void main(String[] args) { List<String> words = Arrays.asList("a", "b", "c"); //传统方式比较排序 // words.sort(new Comparator<String>() { // @Override // public int compare(String o1, String o2) { // return o2.compareTo(o1); // } // }); //Lambda表达式实现 // words.sort((String o1,String o2) -> { // return o2.compareTo(o1); // }); //继续优化 words.sort((o1,o2) ->o2.compareTo(o1)); for (String word: words) { System.out.print(word); } } }
方法引用
1. 引用静态方法 String::valueOf
2. 引用对象的实例方法 x::toString
3.引用某个类型的任意对象的实例方法 String::toString
4.引用类构造函数 String::new
public class PersonInfo implements Comparable<PersonInfo> { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public int compareTo(PersonInfo o) { return this.getName().compareTo(o.getName()); } public int compare(PersonInfo p1 , PersonInfo p2){ return p1.getName().compareTo(p2.getName()); } }
/** * Created by xingyuchao on 2018/1/19. * 工厂方法,将PersonInfo包装成函数式接口的方式 */ public class PersonInfoFactory { private Supplier<PersonInfo> supplier; public PersonInfoFactory(Supplier<PersonInfo> supplier){ this.supplier = supplier; } public PersonInfo getPerson(){ return supplier.get(); } }
public class MainDemo4 { public static void main(String[] args) { //引用类构造函数 String::new PersonInfoFactory personInfoFactory = new PersonInfoFactory(PersonInfo::new); List<PersonInfo> personInfoList = new ArrayList<>(); PersonInfo personInfo1 = personInfoFactory.getPerson(); personInfo1.setName("xingyuchao"); personInfoList.add(personInfo1); PersonInfo personInfo2 = personInfoFactory.getPerson(); personInfo2.setName("admin"); personInfoList.add(personInfo2); PersonInfo personInfo3 = personInfoFactory.getPerson(); personInfo3.setName("china"); personInfoList.add(personInfo3); //传统方式 personInfoList.sort(new Comparator<PersonInfo>() { @Override public int compare(PersonInfo o1, PersonInfo o2) { return 0; } }); print(personInfoList); //引用对象的实例方法 x::toString //personInfoList.sort(personInfo1::compare); //引用某个类型的任意对象的实例方法 String::toString //personInfoList.sort(PersonInfo::compareTo); //引用静态方法 String::valueOf personInfoList.sort(MainDemo4::myCompare); print(personInfoList); } public static void print(List<PersonInfo> personInfos){ personInfos.forEach(personInfo -> System.out.print(personInfo.getName()+" ")); System.out.println(); } private static int myCompare(PersonInfo p1 , PersonInfo p2){ return p1.getName().compareTo(p2.getName()); } }
流式操作
根据返回结果:分为中间操作和最终操作(flume风格 链式操作)
根据并发性区分: 串行和并行操作
Stream.sequential()
Stream.parallel()
中间操作
Filter过滤器
Sorted 排序
Distinct
SubStream 获取子流
终止操作
forEach
findFirst
public class Person { private String name; private int age; public Person(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; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
public class MainDemo5 { static List<Person> person = new ArrayList<Person>(){ { add(new Person("admin",22)); add(new Person("xingyuchao",25)); } }; public static void main(String[] args) { // person.forEach( // person ->{ // person.setAge(person.getAge() + 5); // System.out.println(person.toString()); // }); // 过滤小于24岁的 person.stream().filter(person -> person.getAge()>24).forEach( person -> System.out.println(person.toString())); } }