Java遍历数组的方式classMain{publicstaticvoidmain(String[]args){int[]nums=newint[10];//遍历nums数组并打印其元素值Arrays.stream(nums).forEach(System.out::print);}}我一直很好奇,这是如何工作的?这里的forEach是在IntConsumer接口中传递的。而IntConsumer接口是可以找到的,它只需要实现一个方法voidaccept(intvalue);相应地,可以使用匿名函数(因为只需要实现一个方法)或者匿名类来实现IntConsumer接口,并将其作为参数传递给Arrays.stream(nums).forEach(newIntConsumer(){@Overridepublicvoidaccept(intvalue){System.out.print(value);}});//两者相同Arrays.stream(nums).forEach(num->{System.out.print(num);});但是为什么可以使用forEach(System.out::print)呢?其实System.out::print传入的参数也可以是int,没有返回值,满足了IntConsumer接口的实现。什么是函数式编程?通过合并现有代码生成我们使用新功能更快地获得更可靠的代码,而不是从头开始编写所有内容。代码通常操作数据,分解、组合和转换数据。函数式编程就是对代码片段进行操作。好处是可以减少代码量,在代码片段中抽象出相同的逻辑,从而更好的维护和修改代码。函数式编程的特点之一:允许将函数本身作为参数传递给另一个函数,也允许返回一个函数。将函数作为参数传递的三种方法的基本原理:通过多态。参数是一个接口类,通过接口类的不同实现,从而实现不同功能的传递。在接口中调用函数,函数的逻辑会根据具体的实现类发生变化。但是不变的是参数、返回值和函数名。//函数式接口,只有一个方法,用来传递函数接口Strategy{Stringapproach(Stringmsg);}//一个实现了Strategy接口的类,目的是实现这个接口类的方法SoftimplementsStrategy{publicStringapproach(Stringmsg){returnmsg.toLowerCase()+"?";}}//一个与Strategy无关的类classUnrelated{staticStringtwice(Stringmsg){returnmsg+""+msg;}}publicclassStrategize{策略策略;字符串消息;Strategize(Stringmsg){strategy=newSoft();//[1]this.msg=msg;}publicstaticvoidmain(String[]args){//一个接口Strategy[]strategies={//Strategy是一个接口,使用匿名内部类实现newStrategy(){publicStringapproach(Stringmsg){返回msg.toUpperCase()+"!";}},//匿名函数Lambda表达式msg->msg.substring(0,5)//方法引用Java8的支持后可以发现,approach方法和twice方法都接受一个String参数,但是Unrelated和Strategy接口无关,比如继承、应用接口等Unrelated::twice};Strategizes=newStrategize("你好");s.communicate();for(StrategynewStrategy:strategies){//通过接口的不同实现类,可以将函数作为参数传入,得到不同的结果s.changeStrategy(newStrategy);s.communicate();}}//调用接口方法voidcommunicate(){System.out.println(strategy.approach(msg));}//替换接口实例voidchangeStrategy(Strategystrategy){this.strategy=strategy;}}方法参考Java8后支持。基本结构是[type|objectname]::methodname//functionalinterfaceinterfaceCallable{voidcall(Strings);}classFather{privateStringname;//静态方法staticvoidfind(Stringmsg){System.out.println("Ifinda"+msg);}voidsetName(Stringname){this.name=name;System.out.println(this.name);}}民众classMain{publicstaticvoidmain(String[]args){//可以看作是将Father中的find函数赋值给了Callable接口Callablecall=Father::find;call.call("儿子");//实例化A类Fatherfather=newFather();//接口方法由实例的setName实现Callablecall_1=father::setName;call_1.call("杰克");}}甚至支持构造函数接口的映射MakeNoArgs{Dogmake();}classDog{Stringname;Dog(){name="Jack";}}publicstaticvoidmain(String[]args){MakeNoArgsmna=Dog::new;//MakeNoArgs接口的Make方法由Dog的实例化方法实现DogmyDog=mna.make();}@FunctionalInterface函数式接口函数式接口:这个接口只有一个抽象方法函数式接口仍然是接口,只是在接口的基础上,加了一个条件而已,也就是只有一个抽象方法方法。另外,可以作为普通接口,标注在函数式接口上,告诉编译器检查只有一个方法实现接口==这个注解是可选的==接口只包含一个抽象方法,可以称为功能接口。上面的接口应该加上这个注释,告诉编译器检查这些接口是否只有一个抽象方法//编译失败,函数式接口应该只有一个抽象方法,而接口有两个抽象方法!@FunctionalInterfaceinterfaceNotFunctional{//两个抽象方法,不允许Stringgoodbye(Stringarg);字符串你好(字符串arg);}请注意,具有默认实现的方法不算作抽象方法。如果一个接口声明了一个抽象方法来覆盖java.lang的公共方法。该实现具有来自java.lang.Object或其他地方的实现@FunctionalInterfaceinterfaceNotFunctional{Stringgoodbye(Stringarg);//不算抽象方法,NotFunctional类仍然算作只有一个抽象方法defaultStringhello(Stringarg){System.out.print(arg);返回参数;}}Java中有哪些函数式接口?最常见的是Comparator接口,Runnable接口例子,需要输入两个整数,一个函数(函数接受两个整数,返回一个整数)。当两个整数执行这个函数时,两个整数必须都是-100才能执行传递的函数并返回结果@FunctionalInterfaceinterfaceTransform{inttransform(intnum1,intnum2);}publicclassMain{publicstaticintdoTransform(intnum1,intnum2,Transformtra){num1-=100;num2-=100;返回tra.transform(num1,num2);}publicstaticintadd(intnum1,intnum2){returnnum1+num2;}publicstaticintmultiple(intnum1,intnum2){returnnum1*num2;}publicstaticvoidmain(String[]args){intnum1=200;整数num2=200;System.out.println(doTransform(num1,num2,Main::add));System.out.println(doTransform(num1,num2,Main::multiple));}}//或使用Java内置函数式接口publicclassMain{publicstaticintdoTransform(intnum1,intnum2,BiFunction
