函数式接口

函数式接口:有且只有一个抽象方法的接口,(可以包含其他默认,静态,私有方法)

//函数式接口的使用,创建一个函数式接口
public interface FunctionalInterfaceDemo{
public abstract void method();
}
//实现函数式接口
public class FunctionalInterfaceDemoImpl implements FunctionalInterfaceDemo{
public void method(){
System.out.println("我实现了函数式接口");
}
}
public class Test{
public static void main(String[] args){
//参数是接口,使用接口的实现类对象来调用method方法
show(new FunctionalInterfaceDemoImpl());
//参数是接口,使用接口的匿名内部类来调用方法
show(new FunctionalInterfaceDemo() {
public void method() {
System.out.println("我使用了接口的匿名内部类");
}
});
//函数式接口,可以使用Lambda表达式
//(参数的内容)->{方法体}
show(()->{
System.out.println("使用lambda表达式");
});
} public static void show(FunctionalInterfaceDemo fid){
fid.method();
}
}
//我实现了函数式接口
//我使用了接口的匿名内部类
//使用lambda表达式

性能浪费的日志案例

public class LoggerDemo{
public static void main(String[] args){
String msg1 = "Hello";
String msg2 = "World";
String msg3 = "Java"; showLog(1,msg1+msg2+msg3);
} public static void showLog(int level,String message){
//这里如果输入的不是1,那么前面的字符串就会白拼接了
//造成了性能浪费
if(level==1){
System.out.println(message);
}
}
}

使用Lambda优化日志

//Lambda特点,延迟加载
public class LambdaDemo2{
public static void main(String[] args){
String msg1 = "Hello";
String msg2 = "World";
String msg3 = "Java";
//方法参数是一个接口,可以传递接口的匿名内部类
showLog(1,new MessageBuilder(){
public String builderMessage(){
return msg1+msg2+msg3;
}
}); //调用方法,接口参数是函数式接口,可以使用的是Lambda表达式
showLog(1,()->{
return msg1+msg2+msg3;
});
//感觉使用匿名内部类作为参数比较好理解,但是使用Lambda表达式的话比较简洁,但是也不好理解,有点抽象
} public static void showLog(int level,MessageBuilder mb){
//如果日记等级是1,就调用MessageBuilder的方法
if(level == 1){
//不等于1的话,这一段就不会执行,就不会调用到方法,就不会拼接字符串,就不会存在性能浪费
System.out.println(mb.builderMessage());
}
}
}

函数式接口作为方法的参数案列

public class RunnableDemo{
public static void main(String[] args){
//调用startThread方法
//方法参数是一个函数式接口,可以使用Lambda表达式
//当然也可以通过接口的实现类对象,或者匿名内部类对象进行传参
//首先使用匿名内部类对象来调用方法
startThread(new Runnable(){
public void run(){
System.out.println(Thread.currentThread().getName()+"-->线程启动");
}
});
//使用Lambda表达式作为参数
startThread(()->{
System.out.println(Thread.currentThread().getName()+"-->线程启动");
}); }
//接口Runnable是一个函数式接口
public static void startThread(Runnable run){
//调用我startThread方法,我就开启一条线程
//Thread类的有一个带Runnable接口的构造方法,
//传递该接口,就可以开启一条线程对象
new Thread(run).start();
}
//大概能理解,但是有点绕
}
函数式接口作为返回值得类型
import java.util.*;
public class ComparatorDemo{
public static void main(String[] args){
String[] arr ={"aaa","b","ccccc","dddddddd"};
//把数组的内容以字符串的形式打印出来
System.out.println(Arrays.toString(arr));
//根据比较器产生的顺序对指定对象组进行排序
Arrays.sort(arr,getComparator());
System.out.println(Arrays.toString(arr));
} //定义一个方法,其返回值类型是Comparator
public static Comparator<String> getComparator(){
return (o1,o2)->o2.length()-o1.length();
}
}
常用的函数式接口_Supplier接口
import java.util.function.*;
/*
* Supplier<T> 接口被称之为生产性接口,接口指定的类型是什么,接口中get方法就会返回一个相同的类型
*/
public class SupplierDemo {
public static void main(String[] args) {
//匿名内部类
System.out.println(getString(new Supplier<String>() {
@Override
public String get() {
//下面的方法getString执行方法体的语句,sp.get(),获取到了"春风扶槛露华浓",传递给main方法,main方法打印输出
return "春风扶槛露华浓";
}
}));
//按照我的理解这里的return 把"云想衣裳花想容"传递给了下面的方法getString,下面的方法再次return回来,所以就打印输出"云想衣裳花想容"
//
String s = getString(()->{
return "云想衣裳花想容";
});
System.out.println(s);
}
//Supplier是一个函数式接口
public static String getString(Supplier<String> sp){
return sp.get();
}
}
//看视频不是很理解,但是写的话自己理清楚思路按照Lambda的格式,一步一步想清楚,勉强能写出来,
//求最大值
import java.util.function.*; public class MaxDemo {
public static void main(String[] args) {
int[] arr= {12,42,33,55,23,75,24};
//调用getMax方法
//参数是一个函数式接口,可以使用Lambda表达式
int maxNum=getMax(()->{
int max=arr[0];
for(int i:arr){
if(i>max){
max=i;
}
}
//要求有返回,必须加return
return max;
});
System.out.println(maxNum);
} public static int getMax(Supplier<Integer> sp){
//调用Supplier的get方法,他会返回指定的类型
return sp.get();
} }
Consumer接口
import java.util.function.*;

public class ConsumerDemo {
public static void main(String[] args) {
//调用method,函数式接口的accept有参数
method("李白",(String name)->{
//方法体写要对name做什么操作
System.out.println("云想衣裳花想容->"+name);
});
}
//Consumer<T>接口是一个消费的数据
//泛型指定什么类型,就可以使用方法accept方法消费什么类型的数据
public static void method(String name,Consumer<String> con){
//当你调用method的时候,你可以对name进行指定的操作
con.accept(name);
}
}

​ 个人总结Lambda表达式的几个知识点

有return语句的方法,L表达式也要跟着return,不然编译不通过,我想不通为什么,反正就是要这样

L表达式要不要加参数,好像是看函数式接口的抽象方法有没有参数

要执行的操作都是在L表达式中的方法体给出

Consumer接口默认方法andThen

andThen:需要两个Consumer接口,可以把两个Consumer接口组合到一起,在对数据进行消费

package demo18;

import java.util.function.Consumer;

public class ConsumerDemo1 {
public static void main(String[] args) {
//调用方法
method("李白",
//可以指定参数类型
(String name)->{
System.out.println("云想衣裳花想容");
},
//也可以不指定参数类型
(name)->{
System.out.println("春风扶槛露华浓"+name);
});
}
public static void method(String name, Consumer<String> con1,Consumer<String> con2){
//默认方法andThen方法可以把两个接口连接在一起,一起消费数据name,
//消费的方式可以在Lambda表达式中给出
con1.andThen(con2).accept(name);
}
}
Consumer接口练习
package demo18;

import java.util.function.*;

public class Test {
public static void main(String[] args) {
//准备一个数组
String[] arr={"孙策,大乔","周瑜,小乔","吕布,貂蝉"};
//调用方法method
method(arr,(s)->{
//遍历获得元素,传递到了这里,
//现在对元素进行切割,切割返回的是一个素组,通过索引0来获取需要的元素
String name= s.split(",")[0];
System.out.print("男: "+name);
},
//遍历获得元素,现在轮到我来对他进行切割,需要1元素
(s)->{
String name1= s.split(",")[1];
System.out.println(" 女 "+name1);
});
}
public static void method(String[] str, Consumer<String> con1,Consumer<String> con2){
//只要调用我,我就把他传递过来的集合给遍历了,获取出每一个元素,让con1和con2一起去操作这个元素
//具体的操作步骤已经在Lambda表达式中给出
for(String s :str){
con1.andThen(con2).accept(s);
} }
}
Prediat接口
package demo18;

import java.util.function.*;

public class PredicateDemo {
public static void main(String[] args) {
//调用方法method
//这个函数式接口Predicate是有参数的
//等一下不要忘记把变量名改一下
boolean b= method("云想衣裳花想容",(String s)->{
return s.equals("春风扶槛露华浓"); });
System.out.println(b);
}
public static boolean method(String s,Predicate<String> pre){
//调用Predicate中的方法test,对传递进来的参数进行判断
//具体的判断步骤可以在Lambda表达式中写出
return pre.test(s);
}
}
Predicate接口_默认方法and
package demo18;

import java.io.InputStream;
import java.util.function.Predicate; public class PredicateDemo1 {
public static void main(String[] args) {
boolean b = method("云想衣裳花想容",(String str)->{
System.out.println(str.length());
return str.length()>5;
},
(String str)->{
return str.contains("花");
});
System.out.println(b);
}
public static boolean method(String str, Predicate<String> pre1 , Predicate<String> pre2){
//对传递过来的str进行判断
//and,两个为true 就返回true
return pre1.and(pre2).test(str);
}
}

Predicate接口_默认方法or和negate

or有一个为true,就为true

negate是取反的意思,

Predicate接口的练习

import java.util.*;
import java.util.function.*; public class Test1 {
public static void main(String[] args) {
String[] array = {"迪丽热巴,女", "古力娜扎,女", "马尔扎哈,男", "赵丽颖,女"};
ArrayList<String> list = method(array,
(String s) -> {
String name = s.split(",")[0];
boolean b1 = name.length() == 4;
return b1;
}
, (String s) -> {
String sex = s.split(",")[1];
boolean b2 = sex.equals("女");
return b2;
});
System.out.println(list);
} public static ArrayList<String> method(String[] arr, Predicate<String> pre1, Predicate<String> pre2) {
//定义一个集合,用来接收条件满足的元素
ArrayList<String> list = new ArrayList<String>();
//对传递进来的参数进行判断
for (String s : arr) {
//在Lambda表达式中进行具体的操作
boolean b = pre1.and(pre2).test(s);
//在Lambda表达式中如果操作完了,就会执行下面这一步
if (b) {
list.add(s);
}
}
return list;
}
}
Function接口

Function接口的抽象方法 R apply(T t),根据类型T的参数获取类型T的结果

import java.util.function.*;

public class FunctionDemo {
public static void main(String[] args) {
String s = "1234";
change(s,(String str)->{
return Integer.parseInt(str); });
}
public static void change(String s, Function<String,Integer> fun){
Integer in = fun.apply(s);
System.out.println(in);
}
}
import java.util.function.*;

public class FunctionDemo {
public static void main(String[] args) {
String s = "123";
change(s,
(String str) -> {
return Integer.parseInt(str) + 10;
}
,(Integer i) -> {
return i + "";
});
} public static void change(String s, Function<String, Integer> fun1, Function<Integer, String> fun2) {
String ss = fun1.andThen(fun2).apply(s);
System.out.println(ss); }
}

笔记-迎难而上之Java基础进阶8的更多相关文章

  1. 笔记-迎难而上之Java基础进阶1

    Collection集合 数组的长度是固定的,集合的长度是可变的 数组中存储的是同一类型的元素,可以存储基本数据类型值.集合存储的都是对象.而且对象的类型可以不一致. 集合框架 import java ...

  2. 笔记-迎难而上之Java基础进阶-终

    使用Stream流的方式,遍历集合 import java.util.*; public class StreamDemo{ public static void main(String[] args ...

  3. 笔记-迎难而上之Java基础进阶7

    序列化流 把对象以流的方式写入到文件中保存,叫做对象的序列化 把文件中保存的对象,以流的方式读取出来,叫做对象大反序列化 对象的序列化流_ObjectOutputtream继承自OutputStrea ...

  4. 笔记-迎难而上之Java基础进阶2

    Set集合 import java.util.*; public class HashSetDemo{ public static void main(String[] args){ //Set接口的 ...

  5. 笔记-迎难而上之Java基础进阶3

    统计字符串中每一个不同的字符 import java.util.*; //统计字符串每一个字符出现的字数 public class StringDemo{ public static void mai ...

  6. 笔记-迎难而上之Java基础进阶6

    import java.io.*; public class InputStreamDemo{ public static void main(String[] args) throws IOExce ...

  7. 笔记-迎难而上之Java基础进阶5

    Lambda表达式无参数无返回值的练习 //定义一个接口 public interface Cook{ public abstract void makeFood(); } public class ...

  8. 笔记-迎难而上之Java基础进阶4

    内部类创建多线程 //匿名内部类创建多线程 public class InnerClassThread{ public static void main(String[] args){ //回忆一下之 ...

  9. 第二十八节:Java基础-进阶继承,抽象类,接口

    前言 Java基础-进阶继承,抽象类,接口 进阶继承 class Stu { int age = 1; } class Stuo extends Stu { int agee = 2; } class ...

随机推荐

  1. visual studio 2010 自带reporting报表本地加载的使用

    原文:visual studio 2010 自带reporting报表本地加载的使用 在这家公司时间不长,接触都是之前没玩过的东东,先是工作流引擎和各种邮件短信的审核信息,后又是部署reporting ...

  2. 【bzoj3339】Rmq Problem

    [bzoj3339]Rmq Problem   Description Input Output Sample Input 7 50 2 1 0 1 3 21 32 31 43 62 7 Sample ...

  3. Maven web项目的项目如何创建

    1.eclipse--创建maven项目--选择打包方式为war 2.此时项目还缺少一些东西,比如web-inf,web.xml配置文件之类的 3.项目右键-properties-project fa ...

  4. NOI p 2017 TG游记

    嗨小朋友们大家好 还记得我是谁吗 对了我就是为iot配音的演员 弹鸡鸡 今天呐我特别的要向长沙市的oier们 洛谷的oier们 还有cnblogs的oier们问声好 为什么呢 因为我们在2017年11 ...

  5. Python+Selenium练习篇之18-获取元素上面的文字

    本文介绍如何通过Selenium方法来获取某一个元素的text属性值.在很多自动化测试脚本中,需要多次获取元素的text值,拿过来进行对比和匹配.例如,在一个登陆界面,如果不输入用户名和密码,直接点击 ...

  6. Memcached相关内容总结

    1.Memcached常用命令总结 Memcached命令格式一般为: command 其中描述如下: 参数 描述 command 操作命令,一般为set/add/replace/get/delete ...

  7. CSU-2034 Column Addition

    CSU-2034 Column Addition Description A multi-digit column addition is a formula on adding two intege ...

  8. 【Luogu】P4219大融合(LCT)

    题目链接 LCTrotate打错尬死 容易发现本题就是问两边子树大小乘积,于是开个数组动态维护LCT每个节点虚子树上有多少点,在Access和Link的时候更新即可. #include<cstd ...

  9. css选择器位置和数量技巧

    1. 除去首个元素 li:not(:first-child) li + li li:first-child ~ li 2. 第1-3个元素 li:nth-child(-n+3) 3. 除去第1-3个元 ...

  10. ubuntu 忘记密码,忘记root密码的解决办法

    ubuntu的root默认是禁止使用的,在安装的时候也没有要求设置root的密码.要使用,给root设置密码就行了,sudo passwd root .如果只是普通用户密码忘了,用root就可以修改. ...