1、Lambda的作用:用于简化匿名内部类的书写
我们可以用下面的格式编写Lambda
(被重写方法的形参列表)-> {
被重写方法的方法体代码;
}
需要说明的是,使用Lambda表达式之前,必须先有一个接口,而且接口中只能有一个抽象方 法。(注意:不能是抽象类,只能是接口) 像这样的接口,我们称之为函数式接口,只有基于函数式接口的匿名内部类才能被Lambda表达式简化。public interface Swimming{
void swim();
}
有了Swimming接口之后,使用Lambda表达式,简化匿名内部类书写。
public class Test {
public static void main(String[] args) {
Swimming s = new Swimming(){
@Override
public void swim() {
System.out.println("游泳");
}
};
s.swim();
//使用Lambda表达式对Swimming接口的匿名内部类进行简化
Swimming s1 = () -> {
System.out.println("游泳");
};
s1.swim();
}
}
Lamdba表达式的几种简化写法
(1).Lambda的标准格式
(参数类型1 参数名1, 参数类型2 参数名2)->{
...方法体的代码...
retrurn 返回值;
}
(2).在标准格式的基础上()中的参数类型可以直接省略
(参数名1, 参数名2)->{
...方法体的代码...
return 返回值;
}
(3).如果{}总的语句只有一条语句,则{}可以省略、return关键字、以及最后的“;”都可以省略
(参数名1, 参数名2)-> 结果
(4).如果()里面只有一个参数,则()可以省略
(参数名)->结果
2、Java中异常分为哪两种?
编译时异常
运行时异常
3、异常的处理机制有几种?
异常捕捉:try…catch…finally,异常抛出:throws。
4、如何自定义一个异常?
继承一个异常类,RumtimeException或者Exception
5、try catch fifinally,try里有return,finally还执行么?
finally
代码块中的代码总会执行,不管 try
代码块中是否有 return
语句。
6、Thow与thorws区别
throw
是一个关键字,用于手动抛出一个异常对象。它用在方法体或代码块中,用于显式地抛出一个异常,使得程序可以在需要时中断当前的正常执行流程,并传递一个异常对象给调用者或异常处理机制。
例如:
throw new IllegalArgumentException("Invalid input");
Throws
是方法声明中的一部分,用于指定可能会由该方法抛出的异常类型。当一个方法可能会抛出异常,但并不处理该异常,而是将其传播给调用者处理时,就需要在方法声明中使用 throws
关键字。
例如:
public void readFile() throws IOException, FileNotFoundException {
// 方法体
}
7、HashMap扩容机制
HashMap通过负载因子来衡量其容量的使用程度。当HashMap中的元素数量达到容量乘以负载因子时,默认为0.75,HashMap会触发扩容操作。
当HashMap需要扩容时,会创建一个新的更大的数组,然后将所有的键值对重新分配到新的数组中。
HashMap在初始化时会选择一个初始容量,默认是16,同时也可以在构造函数中指定。
扩容时,HashMap会将容量扩大为当前容量的两倍。
8、ArrayList底层
ArrayList内部维护了一个Object类型的数组,用于存储元素。初始时,数组的大小为默认值或用户指定的初始容量。
当向ArrayList中添加元素时,如果当前数组已满,ArrayList会触发扩展操作。
扩展操作一般会创建一个新的数组,通常是当前数组大小的1.5倍(Java 6及之前版本是1.5倍,Java 7及之后版本是1.5倍加1)。然后将旧数组中的元素复制到新数组中。
ArrayList在大多数情况下提供了很好的性能,特别是在需要频繁读取元素或随机访问时。然而,插入和删除操作的性能可能受到数组拷贝的影响,特别是在元素数量较大时。
9、静态类启动会创建对象吗?
静态成员类在启动时不会自动创建对象。只有在显式实例化静态成员类时,才会创建其对象。
10、如果要用正则表达式对邮箱进行判断,要怎么写正则表达式?
以下是一个简单的示例,涵盖了常见的邮箱格式要求:
String regex = "^[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]{2,})+$";
这个正则表达式的解释如下:
^
表示匹配字符串的开始。[a-zA-Z0-9_]+
匹配邮箱的用户名部分,可以包含大小写字母、数字和下划线,至少一个字符。@
匹配邮箱地址中的@
符号。[a-zA-Z0-9]+
匹配邮箱地址中@
后面的域名部分,可以包含大小写字母和数字,至少一个字符。(\\.[a-zA-Z]{2,})+
匹配邮箱地址中的域名后缀,以.
开头,后面是至少两个字母的字符串,可以有多个域名后缀,例如.com
、.org
等。$
表示匹配字符串的结束。
11、什么是饿汉式和懒汉式?
饿汉式和懒汉式是两种常见的单例设计模式的实现方式,用于确保在整个应用程序生命周期内只有一个实例被创建和使用。
在饿汉式中,单例实例在类加载的时候就被创建,因此称为“饿汉式”,因为它比较“饥渴”。具体实现如下:
public class Singleton {
// 在类加载时就创建实例
private static final Singleton instance = new Singleton();
// 私有构造方法,防止外部实例化
private Singleton() {
}
// 提供全局访问点获取实例
public static Singleton getInstance() {
return instance;
}
}
特点:
- 线程安全:在类加载的时候就创建了实例,因此不存在多线程访问时的竞争问题。
- 简单易实现:实现简单直接,没有复杂的线程同步问题。
- 资源浪费:可能在应用程序启动时就创建实例,如果实例很大或者初始化很耗时,会增加启动时间和内存消耗。
在懒汉式中,单例实例在第一次被使用时才被创建,因此称为“懒汉式”,因为它比较“懒惰”。具体实现如下:
public class Singleton {
// 声明但不初始化实例
private static Singleton instance;
// 私有构造方法,防止外部实例化
private Singleton() {
}
// 提供全局访问点获取实例,使用双重检查锁定(Double-Checked Locking)确保线程安全
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
特点:
- 延迟加载:在第一次调用
getInstance()
方法时才会创建实例,避免了启动时的资源浪费。 - 线程安全:通过双重检查锁定(Double-Checked Locking)机制来保证多线程环境下的线程安全性。
- 复杂性增加:实现相对于饿汉式更复杂,需要处理线程安全问题,例如使用双重检查锁定或者静态内部类等方式。