Java基础之java8新特性(1)Lambda
一、接口的默认方法、static方法、default方法。
1、接口的默认方法
在Java8之前,Java中接口里面的默认方法都是public abstract 修饰的抽象方法,抽象方法并没有方法实体。
public class Test_interface {
public static void main(String[] args) {
pubInterface ts = new MyInterface();
ts.fun1();
}
} //测试接口
interface pubInterface{
public void fun1();//抽象方法
} //接口的实现类
class MyInterface implements pubInterface{
@Override
public void fun1() {
System.out.println("你好我是TestStatic的实现类");
}
}
2、static方法
在Java8中,接口里面可以用static修饰有方法实体的方法。
(1)、使用static修饰的接口中的方法必须要有实体。
(2)、接口的static方法只能够被接口本身调用:接口名.方法名(…)。
(3)、接口的static方法不能够被子接口继承。
(4)、接口的static方法不能够被实现类重写或者调用。
public class Test_interface {
public static void main(String[] args) {
//该接口直接可以调用static方法,但是不能够调用普通抽象方法。
StaInterface.fun2();
//报错可以得知,static方法是不能够被继承的
SonInterface.fun2();
}
} //测试接口
interface StaInterface{
public void fun1();//抽象方法
static void fun2(){
System.out.println("我是static方法……");
}
} //接口的实现类
class MyInterface implements StaInterface{
/**只能够重写抽象方法,不能重写static修饰的方法*/
@Override
public void fun1() { }
} //子接口
interface SonInterface extends StaInterface{ }
3、default方法:
接口的default方法必须有主体
接口的default方法不能被本身接口调用,
接口的default方法可以被子接口继承
接口的default方法可以被实现类复写以及调用
public class Test_interface {
public static void main(String[] args) {
//该接口直接可以调用static方法,但是不能够调用普通抽象方法。
StaInterface.fun2();
//报错可以得知,static方法是不能够被继承的
SonInterface.fun2(); //default方法与普通抽象方法是可以
StaInterface sf = new MyInterface();
sf.fun1();
sf.fun3();
}
} //测试接口
interface StaInterface{
public void fun1();//抽象方法
//static 方法
static void fun2(){
System.out.println("我是static方法……");
}
//default方法
default void fun3(){
System.out.println("我是default方法……");
}
} //接口的实现类
class MyInterface implements StaInterface{
/**只能够重写抽象方法,不能重写static修饰的方法*/
@Override
public void fun1() { } //是可以重写default方法的。
@Override
public void fun3() { } } //子接口
interface SonInterface extends StaInterface{ }
二、函数式接口
1、什么是函数式接口:
函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。函数式接口可以被隐式转换为lambda表达式。
接口注解:@FunctionalInterface
初体验:
(1)、两个参数,有返回值
public class Lambda_one {
public static void main(String[] args) {
//匿名内部类的方式
StaInterface se = new StaInterface() {
@Override
public int sum(int num1, int num2) {
return num1 +num2;
}
};
System.out.println(se.sum(1,3)); //lambda表达式写法
StaInterface seLa1 = (int num1, int num2) -> {
return num1 + num2;
};
System.out.println("Lambda表达式一:" + seLa1.sum(1,3)); /**
* lambda表达式简写
* 1、形参列表中的表达式可以不写,会自行推断
* 2、如果方法体中的代码只有一句,可以省略{},如果return返回的是数据,可以省略return
*/
StaInterface seLa2 = (num1, num2) -> num1 + num2;
System.out.println("Lambda表达式二:" + seLa2.sum(1,2)); }
} //测试接口
@FunctionalInterface
interface StaInterface{
public int sum(int num1,int num2);//抽象方法
}
(2)、一个参数,无返回值
public class Lamdba_two {
public static void main(String[] args) {
//匿名内部类
StaInterface1 s1 = new StaInterface1() {
@Override
public void getStr(String str) {
System.out.println(str);
}
};
s1.getStr("HelloWorld!!!"); //lambda表达式写法
StaInterface1 s2 = (String str) -> {
System.out.println(str);
};
s2.getStr("Lambda表达式一:"+ "Helloworld一"); StaInterface1 s3 = str -> System.out.println(str);
s3.getStr("Lambda表达式二:"+ "Helloworld二");
}
} //测试接口
@FunctionalInterface
interface StaInterface1{
public void getStr(String str);//抽象方法
}
(3)、无参数,无返回值
public class Lambda_three {
public static void main(String[] args) {
StaInterface2 s1 = new StaInterface2() {
@Override
public void getStr() {
System.out.println("HelloWorld");
}
};
s1.getStr(); //Lambda表达式
StaInterface2 s2 = () -> {
System.out.println("Lamdba表达式一:" + "HelloWorld一");
};
s2.getStr(); //Lamdba表达式简化,我们可以这么写,但是没有实际意义
StaInterface2 s3 = () -> {};
s3.getStr();
}
} //测试接口
@FunctionalInterface
interface StaInterface2{
public void getStr();//抽象方法
}
三、Lambda表达式
1、什么是Lambda表达式
简单的说:可以看成是对匿名内部类的简写,使用Lambda表达式时候,接口必须是函数式接口。
2、Lambda表达式语法
基本语法:
<函数式接口> <变量名> = (参数1,参数2……)->{
//方法体
}
3、特点:
(1)、=右边的类型会根据左边的函数式接口类型自动推断;
(2)、如果形参列表为空,只需要保留()
(3)、如果形参只有一个,()可以省略,只需要参数名称即可;
(4)、如果执行语句只有一句,且并没有返回值,{}可以省略,如果有返回值,若想省去{},则必须同时省略return,并且执行语句也保证只有一句。
(5)、形参列表的数据类型会自动推断。
(6)、Lamdba不会生成一个单独的内部类文件。
(7)、lambda表达式如果访问了局部变量,则局部变量必须是final的,若是局部变量没有加final关键字,系统会自动添加,此后在修改局部变量,会报错。
4、Lambda作用域
在Lambda表达式中访问外层作用域和老版本的匿名对象中的方式很相似(我们在学习匿名内部类时候,匿名内部类在访问局部变量的时候,局部变量是被final修饰的),你可以直接访问标记了final的外层局部变量,或者实例的字段以及静态变量,但是如果访问局部变量,要求局部变量必须是final修饰的。
注意:我们Java8新特性里面,匿名内部类访问局部变量,局部变量不需要再用final修饰了,因为Java8已经帮我们写过了,所以我们可以省略。
(1)、匿名内部类举例
public class Lambda_four {
public static void main(String[] args) {
int age = 9;
StaInterface3 s1 = new StaInterface3() {
@Override
public void getStr() {
System.out.println(age);
//注意,当我们在下面对age重新赋值时候,这里的age就报错了,
// 因为,Java8隐式的对age加上final了
}
};
s1.getStr();
age = 10;
}
} interface StaInterface3{
public void getStr();//抽象方法
}
(2)、Lambda表达式举例
public class Lambda_four {
public static void main(String[] args) {
int age = 9;
StaInterface3 s2 = () ->{
System.out.println(age);
//注意,当我们在下面对age重新赋值时候,这里的age就报错了,
// 因为,Java8隐式的对age加上final了
};
age = 10;
}
} interface StaInterface3{
public void getStr();//抽象方法
}
四、方法的引用
1、构造方法的引用
public class Lambda_five {
/*需求:
* 1、有一个Person类
* 2、有一个获得Person对象的接口工厂
* 3、想通过工厂获得一个Person对象
* 4、需要现有一个实际的工厂对象
*/
public static void main(String[] args) {
//使用匿名内部类
PersonFactory py = new PersonFactory() {
@Override
public Person createPerson(String firstName, String lastName) {
return new Person(firstName,lastName);
}
};
Person person1 = py.createPerson("du", "yahui");
System.out.println(person1); //使用Lambda表达式
PersonFactory py1 = (firstName,lastName) ->{
return new Person(firstName,lastName);
};
Person person2 = py1.createPerson("mi", "li");
System.out.println(person2); //简写Lambda表达式
PersonFactory py2 = (firstName,lastName) -> new Person(firstName,lastName);
Person person3 = py2.createPerson("haha","gaga");
System.out.println(person3);
}
}
2、静态方法的引用,把String转成num
public class Lambda_six {
public static void main(String[] args) {
ParseLambda pa = new ParseLambda() {
@Override
public int parseInteger(String num) {
return Integer.parseInt(num);
}
};
int i1 = pa.parseInteger("12");
System.out.println(i1); //使用Lambda表达式
// ParseLambda p = (String num) ->{
// return Integer.parseInt(num);
// };
ParseLambda pa1 = num -> Integer.parseInt(num);
int i2 = pa1.parseInteger("123");
System.out.println(i2); //Lambda简写
ParseLambda pa3 = Integer :: parseInt;
int i3 = pa3.parseInteger("777");
System.out.println(i3);
}
} interface ParseLambda{
int parseInteger(String num);
}
五、四大核心函数式接口
/*
* Java8 内置的四大核心函数式接口
*
* Consumer<T> : 消费型接口
* void accept(T t);
*
* Supplier<T> : 供给型接口
* T get();
*
* Function<T, R> : 函数型接口
* R apply(T t);
*
* Predicate<T> : 断言型接口
* boolean test(T t);
*
*/
public class Lambda_One {
//Consumer<T> 消费型接口 :也就是,给一个参数,操作这个参数
@Test
public void test1(){
happy(1000,(money) -> System.out.println("出去共消费了" + money + "元"));
}
public void happy(double money, Consumer<Double> con){
con.accept(money);
} //Supplier<T> 供给型接口 :产生一些对象
@Test
public void test2(){
List<Integer> listNum = getListNum(10,() -> (int)(Math.random() * 100));
for (Integer integer : listNum) {
System.out.println(integer);
}
}
//需求:产生指定个数的整数,并放入集合中
public List<Integer> getListNum(int num, Supplier<Integer> sup){
List<Integer> list = new ArrayList<Integer>();
for(int i = 0; i < num; i++){
list.add(sup.get());
}
return list;
} //Function<T, R> 函数型接口:传入一个T,返回一个R
@Test
public void test3(){
String s1 = stringHander(" Helloworld !!!",(str) -> str.trim());
System.out.println(s1);
String s2 = stringHander(" Helloworld !!!",(str) -> str.substring(7));
System.out.println(s2);
}
//需求:处理字符串
public String stringHander(String str, Function<String,String> fun){
return fun.apply(str);
} //Predicate<T> 断言型接口:用于做一下判断
@Test
public void test4(){
List<String> list = Arrays.asList("Hello", "atguigu", "Lambda", "www", "ok");
List<String> listStr = filterStr(list,(str) -> str.length() > 3);
for (String s : listStr) {
System.out.println(s);
}
}
//需求:将满足条件的字符串,放入集合中
public List<String> filterStr(List<String> list, Predicate<String> pre){
List<String> strList = new ArrayList<>(); for (String str : list) {
if(pre.test(str)){
strList.add(str);
}
} return strList;
}
}
其他接口:
Java基础之java8新特性(1)Lambda的更多相关文章
- 【Java基础】Java8 新特性
Java8 新特性 Lambda 表达式 Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递).使用它可以写出更简洁.更灵活的代码. L ...
- java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合
java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合 比如,我有一张表: entity Category.java service CategoryServic ...
- Java8 新特性学习 Lambda表达式 和 Stream 用法案例
Java8 新特性学习 Lambda表达式 和 Stream 用法案例 学习参考文章: https://www.cnblogs.com/coprince/p/8692972.html 1.使用lamb ...
- Java8新特性系列-Lambda
转载自:Java8新特性系列-Lambda – 微爱博客 Lambda Expressions in Java 8 Lambda 表达式是 Java 8 最流行的特性.它们将函数式编程概念引入 Jav ...
- 【Java8新特性】Lambda表达式基础语法,都在这儿了!!
写在前面 前面积极响应读者的需求,写了两篇Java新特性的文章.有小伙伴留言说:感觉Lambda表达式很强大啊!一行代码就能够搞定那么多功能!我想学习下Lambda表达式的语法,可以吗?我的回答是:没 ...
- 零基础学习java------21---------动态代理,java8新特性(lambda, stream,DateApi)
1. 动态代理 在一个方法前后加内容,最简单直观的方法就是直接在代码上加内容(如数据库中的事务),但这样写不够灵活,并且代码可维护性差,所以就需要引入动态代理 1.1 静态代理实现 在讲动态代理之前, ...
- Java学习之==>Java8 新特性详解
一.简介 Java 8 已经发布很久了,很多报道表明Java 8 是一次重大的版本升级.Java 8是 Java 自 Java 5(发布于2004年)之后的最重要的版本.这个版本包含语言.编译器.库. ...
- 【Java8新特性】- Lambda表达式
Java8新特性 - Lambda表达式 生命不息,写作不止 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! ...
- Java系列 - 用Java8新特性进行Java开发太爽了
本人博客文章网址:https://www.peretang.com/using-java8s-new-features-to-coding-is-awesome/ 前言 从开始写博客到现在已经过去3个 ...
随机推荐
- java基础-java与c#的可变参数
正文 可变参数,必须最为参数的最后一个参数:可变参数只能有一个: c#可变参数例子: class Program { static void Main(string[] args) { T ...
- Java | 内部类(Inner Class)
前言 本文内容主要来自 Java 官方教程中的<嵌套类>章节. 本文提供的是 JDK 14 的示例代码. 定义 内部类(Inner Class),是 Java 中对类的一种定义方式,是嵌套 ...
- 锐捷交换机18010-X端口假死现象
一次上架锐捷交换机,由于ODF光衰不稳定,导致交换机端口down,排查很多发现以下故障: 重置18010-X端口发现提示一下命令: Port in violation! Use 'errdisable ...
- Python实用笔记 (22)面向对象编程——实例属性和类属性
由于Python是动态语言,根据类创建的实例可以任意绑定属性. 给实例绑定属性的方法是通过实例变量,或者通过self变量: class Student(object): def __init__(se ...
- TypeScript学习——数组、元组、接口(2)
数组 数组类型注解 const numberArr: (number | string)[] = [1, '2', 3]; //既可以是number 也可以是string const stringAr ...
- 致Spring Boot初学者
1.引言 Spring Boot是近两年来火的一塌糊涂,来这里的每一位同学,之前应该大致上学习了web项目开发方面的知识,正在努力成长过程中.因为最近有不少人来向我“请教”,他们大都是一些刚入门的新手 ...
- css完美解决网页在iphoneX的头部刘海显示问题
一.解决iphonX白条,网站扩展到整个屏幕 网页在iphoneX的浏览器屏幕显示上,默认情况下在头部的2侧会出现白条背景,网站被限制在了一个“安全区域”内,移除白色背景的方法 方法一:设置body的 ...
- python—模块optparse的用法
1.什么是optparse: 在工作中我们经常要制定运行脚本的一些参数,因为有些东西是随着我么需求要改变的,所以在为们写程序的时候就一定不能把写死,这样我们就要设置参数 optparse用于处理命令行 ...
- day53 作业
写一个博客首页 <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...
- python面试题六: 剑指offer
面试题3 二维数组中的查找 LeetCode题目:二维数组中,每行从左到右递增,每列从上到下递增,给出一个数,判断它是否在数组中思路:从左下角或者右上角开始比较 def find_integer(ma ...