1 Lambda表达式-Lambda允许把函数作为一个方法的参数(函数作为参数传递进方法中
2 方法引用- 方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
3 stream API-新添加的Stream API(java.util.stream)
4 接口中的静态方法和默认方法-默认方法就是一个在接口里面有了一个实现的方法。
5 optional 类-用来解决空指针异常。
6 Date Time API-加强对日期与时间的处理。
7 函数式接口
default:
在接口中可定义一个使用default修饰有方法体的方法,接口中可以对这个方法提供默认的一种实现。
1、使用default修饰接口中的方法并且必须有主体;
2、接口的default方法不能够被接口本身调用,需要接口的实例(实现类对象)来调用;
3、接口的default方法可以被子接口继承、覆写或者直接调用;
4、接口的default方法可以被实现类覆写及直接调用;
static:
1、使用static修饰接口中的方法并且必须有主体;
2、接口的static方法只能够被接口本身调用;接口名.方法名(...);
3、接口的static方法不能够被子接口继承;
4、接口的static方法不能够被实现类覆写及直接调用;
函数式接口就是有且仅有一个抽象方法的接口,但是可以有多个非抽象方法,函数式接口可以隐式的被转换为Lambda表达式
1.8之前
java.lang.Runnable
java.util.concurrent.Callable
java.security.PrivilegedAction
java.util.Comparator
java.io.FileFilter
java.nio.file.PathMatcher
java.lang.reflect.InvocationHandler
java.beans.PropertyChangeListener
java.awt.event.ActionListener
javax.swing.event.ChangeListener
1.8新增了
java.util.function 此包中包含了很多类,用来支持 Java的 函数式编程
我们在接口前加上
@FunctionalInterface就可以判断该接口是不是函数式接口了
就是对匿名内部类的简写,只有在接口是函数式接口时,才能用Lambda表达式。
先创建一个函数式接口
@FunctionalInterface
public interface ITest {
void test();
}
可以先用匿名内部类的方式表达一下
public class Test {
public static void main(String[] args) {
ITest iTest = new ITest() {
public void test() {
System.out.println("匿名内部类");
}
};
现在再来看Lambda表达式的方法
ITest iTest1 = () -> System.out.println("我是Lambda表达式");
就这一句代码就可以将上面的匿名内部类概括了,这是无参无返回值的写法,接下来让我们来看看有参的情况下Lambda表达式该怎么写
两个参数有返回值的简写**
/*1.方法体只有一句可以省略{}
* 2.如果有返回值 可以省略return
* 3.参数列表类型可以省略掉
* 4.如果参数只有一个左边()小括号可以省略
* /
MyInterface mf = (num1,num2)->num1+num2;
System.out.println(mf.sum(10, 12));
一个参数没有返回值的简写**
接口
public interface MyInterface{
void print(String str);
}
?测试
/*Lambda常规写法*/
MyInterface mi = (String str)->{
System.out.println(str);
};
/*Lambda简写*/
MyInterface mi2 = str->System.out.println(str);
mi2.print("Hello Lambda");
注意:如果基本类型的变量被Lambda使用了就会变为final 修饰的,所以我们重新赋值时就会报错
创建一个User类
public class User {
private String name;
private Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public User(String name) {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
再创建一个UserFactroy工厂接口
@FunctionalInterface
public interface UserFactroy {
User creat(String name,Integer age);
}
/**
* 构造方法的引用
*/
UserFactroy userFactroy1 = User::new;//方法引入语法
UserFactroy userFactroy2 = (name,age) -> new User(name,age);
System.out.println(userFactroy1.creat("za", 12));
//被构造的方法与函数接口的抽象方法入参一致
System.out.println(userFactroy2.creat("zw", 24));
/**
* 静态方法的引用
* 语法 : 类名::静态方法名
* 注意事项:
* 1被引用的静态方法参数列表和函数式接口中抽象方法的参数一致!!
* 2接口的抽象方法没有返回值,引用的静态方法可以有返回值也可以没有
* 3接口的抽象方法有返回值,引用的静态方法必须有相同类型的返回值!!
* * 12/13
*/
//输入一个字符串类型将它转化为integer类型的值
IParse parse = Num::anInt;
//找到类里面的方法,该方法里面的返回值类型应该与接口中的返回值类型一样
System.out.println(parse.parse("222"));
/**
* 方法的引用
* 语法 : 对象名::非静态方法名
* 注意事项:
* 1被引用的实例方法参数列表和函数式接口中抽象方法的参数一致!!
* 2接口的抽象方法没有返回值,引用的实例方法可以有返回值也可以没有
* 3接口的抽象方法有返回值,引用的实例方法必须有相同类型的返回值!!
* 12/13
*/
//
String s = "123";
Function<String, Boolean> function = s::endsWith;
function.apply("123");
Stream(流)是一个来自数据源的元素队列并支持聚合操作
stream() ? 为集合创建串行流。
parallelStream() ? 为集合创建并行流。
forEach- 来迭代流中的每个数据
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8);
list.stream().forEach(System.out::println);
map- 方法用于对每个元素修改
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
// 获取对应的平方数
numbers.stream().map( i -> i*i).forEach(System.out::println);
filter-过滤出想要的元素
List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
//过滤取出每一个不为空的元素
strings.stream().filter(string -> !string.isEmpty()).forEach(System.out::println);
limit-获取指定数量的数据
Random random = new Random();
//从随机流中获取十个随机数:并输出结果
random.ints().limit(10).forEach(System.out::println);
sorted-排序
Random random = new Random();
//获取十个随机数,并排序
random.ints().limit(10).sorted().forEach(System.out::println);
collectors-实现了很多归约操作,例如将流转换成集合和聚合元素
Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。
Optional 类的引入很好的解决空指针异常
善用Optional可以使我们代码中很多繁琐、丑陋的设计变得十分优雅。
Optional.of(T t):创建要给Optional实例
Optional.empty():创建一个空的Optional实例
Optional.ofNullable(T t):若t不为null,创建Optional实例,否则创建空的实例
isPresent():判断是否包含值
orElse(T t):如果调用对象包含值,返回该值,否则返回t
orElseGet(Supplier s):如果调用对象包含值,返回该值,否则返回s获取的值
map(function f):如果有值对其处理,并发挥处理后的Optional ,否则返回Optional.empty()
flatMap(Function mapper):与map类似,要求返回值必须是Optional
Jdk1.8的新特性 lambda表达式 方法引用 函数式接口 stream
多线程 线程的创建方式 生命周期 锁机制 synconized与lock区别 threadlocal原理
线程池 线程池原理 常见4种线程池
线程池中最大线程数的设置