JAVA8新特性
1、函数式编程
主要关注对数据进行了什么操作
1.1 优点
代码简洁
容易理解
易于“并发编程”
2、lamada表达式
(参数列表)->{代码}
未使用
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(123123123);
}
}).start();
使用Lamada表达式
new Thread(() ->{
System.out.println(1111);
}).start();
3 基本语法
一、语法特性1
Java8引入了一个新的操作符号“->”,该操作符称为箭头操作符或者Lamada操作符
左侧:Lamada 表达式的参数列表
右侧:Lamada 表达式中所需执行的功能即 Lamada体
**语法格式1:**无参,无返回值
() -> System.out.println(123123);
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println(123123213);
}
};
r1.run();
Runnable r2 = () -> System.out.println(123123);
r2.run();
public void test(){
int num = 0; // 默认是被final修饰的,num++报错
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println(123123213 + (num++));
//Variable 'num' is accessed from within inner class,
// needs to be final or effectively final
}
};
r1.run();
}
语法格式2: 有参,无返回值
(x) -> System.out.println(x);
@Test
public void test2(){
Consumer<String> consumer = (x) -> System.out.println(x);
consumer.accept("我的工作什么时候才能找到!");
}
语法格式3:若只有一个参数,参数的小括号可以省略不写
x) -> System.out.println(x);
语法格式4:有两个以上参数,有返回值,并且Lamada体中有多条语句
Comparator comparator = (x,y) ->{
System.out.println(“函数式接口”);
return Integer.compare(x,y);
};
@Test
public void test3(){
Comparator<Integer> comparator = (x,y) ->{
System.out.println("函数式接口");
return x.compareTo(y);
};
System.out.println(comparator.compare(2, 1));
}
语法格式5:若Lambda 体中只有一条语句,return 和 大括号都可以省略不写,
Comparator comparator = (x,y) -> Integer.compare(x,y);
语法格式6:Lambda 表达式的参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出,数据类型,即"类型推断";
上联:左右遇一括号省
下联:左侧推断类型省
横批:能省则省
二、Lambda 表达式需要“函数式接口”的支持
函数式接口: 接口中只有一个抽象方法的接口
可以使用注解@FunctionalInterface 修饰,可以检查是否是函数式接口
package com.wang;
@FunctionalInterface
public interface MyFun {
Integer getInteger(Integer num);
}
@Test
public void test5(){
Integer integer = getNum(100,(x)-> x * x);
System.out.println(integer); // 10000
Integer integer1 = getNum(100,(y)-> y + 500);
System.out.println(integer1); // 600
}
public Integer getNum(Integer num,MyFun myFun){
return myFun.getInteger(num);
}
练习题:
题1:
@Test
public void test6(){
List<Student> students = Arrays.asList(
new Student("zs",18),
new Student("ls",10),
new Student("ww",28),
new Student("zl",6)
);
Collections.sort(students,(x,y) -> {
if (x.getAge() == y.getAge()){
return x.getName().compareTo(y.getName());
}else{
return -Integer.compare(x.getAge(),y.getAge());
}
});
for (Student student : students) {
System.out.println(student);
}
}
题2:
String string = getTestInfo("\t\t\t我大尚硅谷威武!! ", (str) -> str.trim());
System.out.println(string); // 我大尚硅谷威武!!
String str12 = getTestInfo("asdasd",str -> str.toUpperCase());
System.out.println(str12); // ASDASD
String str23 = getTestInfo("我大尚硅谷威武",str -> str.substring(2,5));
System.out.println(str23); // 尚硅谷
Java几大核心接口
1、消费型接口
@Test
public void test1(){
testConsumer(10,(x) -> System.out.println("我喜欢,每次花呗" + x));
}
public void testConsumer(Integer num, Consumer consumer){
consumer.accept(num);
}
2、供给型接口
// todo Math.random() 方法生成一个介于 0.0 和 1.0 之间的随机数
List<Integer> list = getList(10,() -> (int)(Math.random() * 10));
for (Integer integer : list) {
System.out.println(integer);
}
}
public List<Integer> getList(Integer num, Supplier<Integer> supplier){
List<Integer> integerList = new ArrayList<>();
for (int i = 1; i < num ; i++) {
integerList.add( i + supplier.get());
}
return integerList;
}
3.函数型接口
/**
* Function 函数型接口
*/
@Test
public void test3(){
String string = getString("我的尚硅谷威武", (str) -> str.substring(2, 5));
System.out.println(string);
}
public String getString(String str, Function<String,String> function){
return function.apply(str);
}
4.断言型接口 boolean
@Test
public void test4(){
List<String> list = Arrays.asList("Hello","atguigu","asd","ok","yrfc");
List<String> filterStr = filterStr(list, (str) -> str.length() > 3);
System.out.println(filterStr);
}
// 过滤符合条件的字符串
public List<String> filterStr(List<String> strings, Predicate<String> predicate){
List<String> stringList = new ArrayList<>();
for (String s : strings) {
if (predicate.test(s)){
stringList.add(s);
}
}
return stringList;
}
方法引用和构造器引用
方法引用
1、对象::实例方法名
@Test
public void test2(){
Student student = new Student("zx",123);
Supplier<Integer> studentConsumer = student::getAge;
System.out.println(studentConsumer.get());
}
@Test
public void test1(){
PrintStream printStream = System.out;
Consumer<Integer> consumer = printStream::print;
consumer.accept(12);
Consumer<String> stringConsumer = System.out::print;
stringConsumer.accept("aaa");
}
注意:Lambda体中的参数列表和返回值类型,要与函数式接口中抽象方法的参数列表和返回值类型保持一致。
// 类名::静态方法名
@Test
public void test3(){
/**
* public static int compare(int x, int y) {
* return (x < y) ? -1 : ((x == y) ? 0 : 1);
* }
*/
Comparator<Integer> com = (x,y) -> Integer.compare(x,y);
Comparator<Integer> com1 = Integer::compareTo;
System.out.println(com1.compare(1, 2));
}
构造器引用 和 数组引用
StreamAPI
筛选和切片
内部迭代和外部迭代
@Test
public void test01(){
List<Student> students = Arrays.asList(
new Student("zs", 18),
new Student("ls", 10),
new Student("ww", 28),
new Student("zl", 6)
);
Stream<Student> stream = students.stream()
.filter(e -> {
System.out.println("看看!!!!!!!!!!!");
return e.getAge() > 10;
});
stream.forEach(System.out::println);
}
结果:
看看!!!!!!!!!!!
Student(name=zs, age=18)
看看!!!!!!!!!!!
看看!!!!!!!!!!!
Student(name=ww, age=28)
看看!!!!!!!!!!!
短路 limit
@Test
public void test2(){
List<Student> students = Arrays.asList(
new Student("zs", 18),
new Student("ls", 10),
new Student("ww", 28),
new Student("zl", 6)
);
students.stream()
.filter(e -> e.getAge() >= 10)
.limit(2)
.forEach(System.out::println);
}
skip 跳过
map和flantMap
List<Student> students = Arrays.asList(
new Student("zs", 18),
new Student("ls", 10),
new Student("ww", 28),
new Student("zl", 6)
);
students.stream()
.map((m) -> m.getName())
.forEach(System.out::println);
zs
ls
ww
zl
flantMap
@Test
public void test3(){
List<String> list = Arrays.asList("aa","df","asdc","grtg");
list.stream()
.flatMap(s -> characterList(s))
.forEach(System.out::println);
}
public static Stream<Character> characterList(String str){
List<Character> list = new ArrayList<>();
char[] charArray = str.toCharArray();
for (char c : charArray) {
list.add(c);
}
return list.stream();
}
排序操作 sorted
终止操作
anyMatch
List<Student> students = Arrays.asList(
new Student("zs", 18,Student.State.BUSY),
new Student("ls", 10,Student.State.FREE),
new Student("ww", 28,Student.State.VOCATION),
new Student("zl", 6,Student.State.FREE)
);
boolean b = students.stream()
.anyMatch((s) -> s.getStatus().equals(Student.State.VOCATION));
System.out.println(b); //true
map 和 reduce
List<Student> students = Arrays.asList(
new Student("zs", 18,Student.State.BUSY),
new Student("ls", 10,Student.State.FREE),
new Student("ww", 28,Student.State.VOCATION),
new Student("zl", 6,Student.State.FREE)
);
Optional<Integer> optionalInteger = students.stream()
.map(Student::getAge)
.reduce(Integer::sum);
System.out.println(optionalInteger.get());
List<Integer> integers = Arrays.asList(12, 34, 5, 6, 7, 86);
Integer reduce = integers.stream().reduce(0, (x, y) -> x + y);
System.out.println(reduce); //150
collect
List<Student> students = Arrays.asList(
new Student("zs", 18,Student.State.BUSY),
new Student("ls", 10,Student.State.FREE),
new Student("ww", 28,Student.State.VOCATION),
new Student("zl", 6,Student.State.FREE),
new Student("zl", 6,Student.State.FREE)
);
List<String> collect = students.stream()
.map(Student::getName)
.collect(Collectors.toList());
collect.forEach(System.out::println);
System.out.println("========================");
Set<String> stringSet = students.stream()
.map(Student::getName)
.collect(Collectors.toSet());
stringSet.forEach(System.out::println);
System.out.println("=======================");
LinkedHashSet<String> linkedHashSet = students.stream()
.map(Student::getName)
.collect(Collectors.toCollection(LinkedHashSet::new));
System.out.println(linkedHashSet);
@Test
public void test4(){
List<Student> students = Arrays.asList(
new Student("zs", 18,Student.State.BUSY),
new Student("ls", 10,Student.State.FREE),
new Student("ww", 28,Student.State.VOCATION),
new Student("zl", 6,Student.State.FREE),
new Student("zl", 6,Student.State.FREE)
);
// 使用分隔符连接
String str = students.stream()
.map(Student::getName)
.collect(Collectors.joining(","));
System.out.println(str);
System.out.println("================");
// 计算元素的个数
Long count = students.stream()
.map(Student::getAge)
.collect(Collectors.counting());
System.out.println(count);
System.out.println("===============");
// 计算年龄总和
Integer integer = students.stream()
.map(Student::getAge)
.collect(Collectors.summingInt(Integer::intValue));
System.out.println(integer);
System.out.println("==========================");
Integer countAge = students.stream()
.collect(Collectors.summingInt(Student::getAge));
System.out.println(countAge);
System.out.println("====================");
// 分组
Map<Student.State, List<Student>> stateListMap = students.stream()
.collect(Collectors.groupingBy(Student::getStatus));
// 第一种遍历
for (Map.Entry<Student.State, List<Student>> listEntry : stateListMap.entrySet()){
Student.State key = listEntry.getKey();
List<Student> value = listEntry.getValue();
System.out.println("status: - -- " + key);
for (Student student : value) {
System.out.println(student);
}
}
// 第二种
stateListMap.forEach(((state, students1) -> System.out.println("state:\t" + state +"-----> student:\t" + students1)));
}
并行流
@Test
public void test5(){
long reduce = LongStream.rangeClosed(0, 1000000L).parallel().reduce(0, Long::sum);
System.out.println(reduce);
}
Optional 类
接口中default 关键字 和 静态方法