Java基础Lambda表达式【四】,高级java面试题及答案整理

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

  • 接口类

/*

定义Addable接口,有且仅有一个抽象方法.

*/

public interface Addable {

/*

定义抽象方法int add(int x,int y)

*/

int add(int x,int y);

}

  • 接口实现类

public class AddableImpl implements Addable{

@Override

public int add(int x, int y) {

return x + y;

}

}

  • 测试类

public class AddableTest {

/*

定义main方法,在main方法中调用useAddable方法.

*/

public static void main(String[] args) {

//创建Addable接口的实现类AddableImpl对象.

AddableImpl addable = new AddableImpl();

//调用useAddable方法,将实现类对象作为参数传递.

useAddable(addable);

//使用匿名内部类的方式实现Addable接口的add方法并且作为参数传递.

useAddable(new Addable() {

@Override

public int add(int x, int y) {

return x/y;

}

});

//使用Lambda表达式实现Addable的add方法并且作为参数传递.

useAddable((int x, int y) -> {return x * y;});

}

/*

定义useAddable方法,需要传递一个Addable接口的实现类作为参数,这里使用多态.

*/

public static void useAddable(Addable addable){

int sum = addable.add(2, 3);

System.out.println(sum);

}

}

2.8.Lambda表达式的省略模式

  • 参数类型可以省略,但是如果有多个参数的情况下,不能只省略一个,要么全部不省略,要么全部省略.

  • 如果参数只有一个,例如(x) -> {},那么包裹x的()可以省略,可以写成x -> {}

  • 如果代码块的语句只有一条,那么可以省略大括号/分号/return关键字.

Lambda表达式与匿名内部类的区别
  • 所需类型不同

  • 匿名内部类可以是接口,也可以是抽象类,也可以是具体类.

  • 代码演示

public class LambdaDemo05 {

public static void main(String[] args) {

//调用useAnimal方法,使用匿名内部类作为参数传递.

useAniaml(new Animal() {

@Override

public void play() {

super.play();

}

});

//调用useStudent方法,使用匿名内部类作为参数传递.

useStudent(new Student(){

@Override

public void study() {

super.study();

}

});

//调用useInter方法,使用匿名内部类作为参数传递.

useInter(new Inter() {

@Override

public void show() {

System.out.println(“Inter的show方法执行了.”);

}

});

}

public static void useAniaml(Animal animal){

animal.play();

}

public static void useStudent(Student student){

student.study();

}

public static void useInter(Inter inter){

inter.show();

}

}

Lambda表达式只能是接口.

  • 使用限制不同

  • 如果接口中有且仅有一个抽象方法,那么可以使用Lambda表达式,也可以使用匿名内部类.

  • 如果接口中有多个抽象方法,那么只能使用匿名内部类实现所有方法,不可以使用Lambda表达式.

  • 实现原理不同

  • 匿名内编译之后会产生一个单独的.class文件.

  • Lambda表达式编译之后不会产生单独的.class文件,对应的字节码会在运行的时候动态生成.

2.9.接口组成更新

  • 接口的组成更新概述

  • 常量

  • public static final

  • 抽象方法

  • public abstract

  • 默认方法 -> Java8提供

  • default 返回值类型 方法名(){}

  • 私有方法 -> Java9提供

  • private 返回值类型 方法名(){}

  • 静态方法 -> Java8提供

  • static 返回值类型 方法名(){}

  • 接口中的默认方法

  • 格式

public default 返回值类型 方法名(参数列表){

方法体;

}

代码演示

public interface DefaultInter {

/*

在接口中定义默认方法.

*/

default void show(){

System.out.println(“DefaultInter中的默认方法执行了.”);

}

}

    • 注意事项
  • 默认方法不是抽象方法,所以Java不强制实现类去实现这个方法,但是这个方法可以被重写,重写的时候去掉default关键字.

  • **public可以省略,**default不可以省略.

  • 如果实现的多个接口中出现同名的默认方法,那么必须重写这个默认方法,否则会报错.

  • 接口中的静态方法

  • 格式

public static 返回值类型 方法名(参数列表){

方法体;

}

  • 代码演示

public interface StaticInter {

/*

接口中定义静态方法.

*/

static void show(){

System.out.println(“StaticInter中的静态方法执行了.”);

}

}

注意事项

  • 接口中的静态方法只可以通过接口调用,实现类不可以调用,因为Java是可以多实现的,当两个接口出现同名静态方法的时候,那么Java无法判断具体要调用哪个接口的静态方法.

  • **public可以省略,**static不可以省略.

接口中的私有方法

  • 格式

private 返回值类型 方法名(参数列表){

方法体;

}

private static 返回值类型 方法名(参数列表){

方法体;

}

  • 代码演示

public interface PrivateInter {

//定义默认方法show01

default void show01(){

System.out.println(“默认方法show01执行了”);

method01();

System.out.println(“默认方法show01结束了”);

}

//定义默认方法show02

default void show02(){

System.out.println(“默认方法show02执行了”);

method02();

System.out.println(“默认方法show02结束了”);

}

//定义静态方法show01

static void show1(){

System.out.println(“静态方法show01执行了”);

method02();

System.out.println(“静态方法show01结束了”);

}

//定义私有方法method01

private void method01(){

System.out.println(“私有方法method01执行了.”);

}

//定义静态私有方法method02

private static void method02(){

System.out.println(“私有静态方法method02执行了.”);

}

}

    • 注意事项
  • 接口中的私有方法只可以被接口中的其他方法调用.

  • 接口中的默认方法可以调用私有的静态方法和非静态方法.

  • 接口中的静态方法只可以调用私有的静态方法.

2.10.方法引用

  • 体验方法引用

  • 方法引用出现的原因

  • 在使用Lambda表达式的时候,我们实际上没有操作对象,而是直接拿参数做操作,直接书写解决方案,那么我们在Lambda中所指定的解决方案,已经有地方存在相同答案,就没有必要写重复逻辑,那么我们如何直接使用已经有的解决方案呢,可以通过方法引用来实现.

  • 方法引用初体验

  • 需求

  • 定义一个接口,PrintAble,里面定义一个抽象方法,void printString(String s).

  • 定义一个测试类,测试类中提供usePrintable(Printable printable)方法和主方法,在主方法中调用usePrintable()方法.

  • 代码演示

  • 接口类

public interface Printable {

void printString(String s);

}

  • 测试类

public class PrintableTest {

public static void main(String[] args) {

//使用Lambda表达式实现Printable接口的printString方法并且作为参数传递.

usePrintable(s -> System.out.println(s));

//使用方法引用

usePrintable(System.out::println );

}

public static void usePrintable(Printable printable){

printable.printString(“黑马程序员.”);

}

}

  • 方法引用符

  • ::

  • 代码分析

  • Lambda表达式写法

//使用Lambda表达式实现Printable接口的printString方法并且作为参数传递.

usePrintable(s -> System.out.println(s));

获取到参数s之后传递到Lambda表达式,传递给System.out.println进行处理.

  • 方法引用写法

//使用方法引用

usePrintable(System.out::println);

直接使用System.out中的println方法来取代Lambda,代码更加简洁.

实际上参数s传递到方法引用中,就无须写明s了,我们对参数进行操作,那么进行什么操作?打印操作,Java已经给我们提供了System.out.println方法,所以我们直接引用方法即可,Java会根据上下文自动推导要使用哪个方法进行使用.

  • 推导与省略

  • 如果使用Lambda,那么根据"可推导就是可省略"的原则,无须指定参数类型,也无须指定重载形式,都将被自动推导.

  • 如果使用方法引用,也可以根据上下文进行推导.

  • 方法引用是Lambda的孪生兄弟.

  • 引用类方法

  • 格式

  • 类名::静态方法

  • Interger::parseInt

  • 需求

  • 定义一个接口(Converter),里面定义一个抽象方法 int convert(String s);

  • 定义一个测试类(ConverterDemo),在测试类中提供两个方法,一个方法是useConverter(Converter c),一个方法是主方法,在主方法中调用useConverter方法.

  • 代码演示

  • 接口类

public interface Converter {

int convert(String s);

}

  • 测试类

public class ConverterTest {

public static void main(String[] args) {

//使用Lambda表达式方法调用useConverter方法.

useConverter(s -> Integer.parseInt(s));

//使用类方法引用调用useConverter方法.

useConverter(Integer::parseInt);

}

public static void useConverter(Converter converter){

int num = converter.convert(“123”);

System.out.println(num);

}

}

    • 注意事项
  • Lambda表达式被类方法替代的时候,它的形式参数全部传递给静态方法作为参数.

  • 引用对象的实例方法 -> 就是引用类中的成员方法

  • 格式

  • 对象::成员方法

  • 需求

  • 定义一个类(PrintString),里面定义一个方法public void printUpper(String s):把字符串参数变成大写的数据,然后在控制台输出.

  • 定义一个接口(Printer),里面定义一个抽象方法void printUpperCase(String s).

  • 定义一个测试类(PrinterDemo),在测试类中提供两个方法,一个方法是:usePrinter(Printer p)一个方法是主方法,在主方法中调用usePrinter方法.

  • 代码演示

  • 自定义类

public class PrintString {

public void printUpper(String s){

System.out.println(s.toUpperCase());

}

}

  • 接口类

public interface Printer {

/*

定义抽象方法

*/

void printUpperCase(String s);

}

  • 测试类

public class PrinterTest {

public static void main(String[] args) {

//创建PrintString对象.

PrintString printString = new PrintString();

//使用Lambda表达式实现Printer接口的printUpperCase方法并且作为参数传递.

usePrinter(s -> System.out.println(s.toUpperCase()));

//我们已经有了直接变化为大写打印的解决方案,所以直接使用方法引用即可,引用printString对象的printUpper方法.

usePrinter(printString::printUpper);

}

public static void usePrinter(Printer printer){

printer.printUpperCase(“hello world”);

}

}

    • 注意事项
  • Lambda被对象的实例方法替代的的时候,它的形式参数会全部传递给该方法作为参数.

  • 引用类的实例方法

  • 格式

  • 类名::成员方法

  • 需求

  • 定义一个接口(MyString),里面定义一个抽象方法:String mySubString(String s,int x,int y).

  • 定义一个测试类(MyStringDemo),在测试类中提供两个方法一个方法是:useMyString(MyString my),一个方法是主方法,在主方法中调用useMyString方法.

  • 代码演示

  • 接口类

public interface MyString {

/*

定义抽象方法

*/

String mySubString(String s,int beginIndex,int endIndex);

}

  • 测试类

public class MyStringTest {

public static void main(String[] args) {

//使用Lambda表达式的实现MyString的mySubString方法并且作为参数传递.

useMyString((s, beginIndex, endIndex) -> s.substring(beginIndex,endIndex));

//直接引用String类提供好的方法SubString方法.

useMyString(String::substring);

}

public static void useMyString(MyString myString){

String s = myString.mySubString(“HelloWorld”, 2, 5);

System.out.println(s);

}

}

  • 注意事项

  • Lambda被类的实体方法替代的时候,第一个参数作为调用者,后面的全部参数传递给该方法作为参数.

  • 引用构造器

  • 格式

  • 类名::new

  • 需求

  • 定义一个类(Student),里面有两个成员变量(name,age),并提供无参构造方法和带参构造方法,以及成员变量对应的get和set方法.

  • 定义一个接口(StudentBuilder),里面定义一个抽象方法,Student build(String name,int age);

  • 定义一个测试类(StudentDemo),在测试类中提供两个方法一个方法是:useStudentBuilder(StudentBuilder s)一个方法是主方法,在主方法中调用useStudentBuilder方法.

  • 代码演示

  • 学生类

public class Student {

private String name;

private int age;

//无参构造方法

public Student() {

2021年Java中高级面试必备知识点总结

在这个部分总结了2019年到目前为止Java常见面试问题,取其面试核心编写成这份文档笔记,从中分析面试官的心理,摸清面试官的“套路”,可以说搞定90%以上的Java中高级面试没一点难度。

本节总结的内容涵盖了:消息队列、Redis缓存、分库分表、读写分离、设计高并发系统、分布式系统、高可用系统、SpringCloud微服务架构等一系列互联网主流高级技术的知识点。

目录:

(上述只是一个整体目录大纲,每个点里面都有如下所示的详细内容,从面试问题——分析面试官心理——剖析面试题——完美解答的一个过程)

部分内容:

对于每一个做技术的来说,学习是不能停止的,小编把2019年到目前为止Java的核心知识提炼出来了,无论你现在是处于什么阶段,如你所见,这份文档的内容无论是对于你找面试工作还是提升技术广度深度都是完美的。

不想被后浪淘汰的话,赶紧搞起来吧,高清完整版一共是888页,需要的话可以点赞+关注

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

法.

  • 代码演示

  • 学生类

public class Student {

private String name;

private int age;

//无参构造方法

public Student() {

2021年Java中高级面试必备知识点总结

在这个部分总结了2019年到目前为止Java常见面试问题,取其面试核心编写成这份文档笔记,从中分析面试官的心理,摸清面试官的“套路”,可以说搞定90%以上的Java中高级面试没一点难度。

本节总结的内容涵盖了:消息队列、Redis缓存、分库分表、读写分离、设计高并发系统、分布式系统、高可用系统、SpringCloud微服务架构等一系列互联网主流高级技术的知识点。

目录:

[外链图片转存中…(img-upSAYtQl-1713619217397)]

(上述只是一个整体目录大纲,每个点里面都有如下所示的详细内容,从面试问题——分析面试官心理——剖析面试题——完美解答的一个过程)

[外链图片转存中…(img-IC2V4Cbv-1713619217398)]

部分内容:

[外链图片转存中…(img-exqbKn43-1713619217398)]

[外链图片转存中…(img-qI8MSQJ1-1713619217399)]

[外链图片转存中…(img-NWjQwEkZ-1713619217399)]

对于每一个做技术的来说,学习是不能停止的,小编把2019年到目前为止Java的核心知识提炼出来了,无论你现在是处于什么阶段,如你所见,这份文档的内容无论是对于你找面试工作还是提升技术广度深度都是完美的。

不想被后浪淘汰的话,赶紧搞起来吧,高清完整版一共是888页,需要的话可以点赞+关注

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-HdzuS6MO-1713619217400)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 25
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值