Java8新特性
Lambda表达式
为什么使用Lambda表达式 如何使用Lambda表达式
package com.sdut.k8.Lambdabds;
/**
* 1.为什么使用Lambda表达式
*
* 2.如何写lambda表达式
* 1)结构
* -> 箭头符号
* 左侧:Lambda表达式的参数列表
* 右侧:Lambda体,lambda表达式主要完成的功能
* 2) *如果左侧没有参数,一定要写(),不能省略
* *如果左侧有一个参数,()和数据类型都可以省略
* *如果左侧有多个参数,数据类型可以省略
* *左侧的参数名只要符号标识符的命名规范就可以
* *如果右侧有多行代码,{}不能省略
* *如果右侧有一行代码,{}、return关键字、;都可以省略
* 3.什么地方可以使用lambda表达式
* 有“函数式接口”的地方就可以用Lambda表达式
* 1)什么是函数式接口
* *首先是一个接口
* *只能有一个抽象方法,可以有静态方法,默认方法,常量
* 2)@FunctionalInterface 用在接口上,表示这是一个函数式接口
* 目的是让编译器协助我们检查这个是不是函数时接口 类似于@Override
* 4.方法引用
* 本质:lambda表达式,Lambda表达式简写
* 什么情况下可以使用方法引用?
* *Lambda表达式方法体({}里的代码)只有一行
* *这一行代码的参数列表,返回值类型和函数式接口抽象方法的参数列表,返回值完全相同
* 如何将Lambda表达式修改为方法引用
* 三种使用情况:
* 对象::实例方法名
* 类::静态方法名
* 类::实例方法名
*
*/
import java.util.ArrayList;
import java.util.function.Consumer;
public class MyTest1 {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Hello World");
}
});
//
//Thread thread1 = new Thread(() -> {
// System.out.println("Goodbye World");
//});
Thread thread1 = new Thread(() -> System.out.println("Goodbye World"));
ArrayList<String> list1 = new ArrayList<>();
list1.add("aaaaaa");
list1.add("bbbbbbb");
list1.add("eeeeeeeeee");
list1.add("zzzzzzzz");
list1.add("sss");
list1.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
System.out.println("-----------------");
//list1.forEach((String s) -> {
// System.out.println(s);
//});
// list1.forEach( s ->System.out.println(s));
//方法引用 对象::实例方法名
list1.forEach(System.out::println);
System.out.println("----------------");
ArrayList<Integer> list2 = new ArrayList<>();
list2.add(20);
list2.add(2);
list2.add(0);
list2.add(-2);
// Collections.sort(list2);
// list2.sort(new Comparator<Integer>() {
// @Override
// public int compare(Integer o1, Integer o2) {
// //return o1 - o2;
// return Integer.compare(o1, o2);
// }
// });
//list2.sort((Integer o1,Integer o2)->{
// return Integer.compare(o1, o2);
//});
list2.sort((o1,o2)-> Integer.compare(o1, o2));
//方法引用 类::静态方法名
list2.sort(Integer::compare);
System.out.println(list2);
ArrayList<String> list3 =new ArrayList<>();
list3.add("aaaaaa");
list3.add("bbbbb");
list3.add("zzzz");
list3.add("33");
//list3.sort((s1,s2) ->s1.compareTo(s2));
//方法引用 类名::实例方法名
list3.sort(String::compareTo);
System.out.println(list3);
}
}
常用的函数式接口 *** 重点要都认识背过
Lambda表达式的层层深入
package com.sdut.k8.Lambdabds;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.function.Predicate;
public class MyTest2 {
public static void main(String[] args) {
ArrayList<Apple> list = new ArrayList<>();
list.add(new Apple(150,"red"));
list.add(new Apple(210,"red"));
list.add(new Apple(300,"yellow"));
list.add(new Apple(90,"green"));
list.add(new Apple(90,"yellow"));
list.add(new Apple(100,"green"));
list.add(new Apple(123,"red"));
匿名内部类
//list.sort(new Comparator<Apple>() {
// @Override
// public int compare(Apple o1, Apple o2) {
// return o1.getWeight().compareTo(o2.getWeight());
// }
//});
//
lambda表达式
//list.sort((Apple o1,Apple o2) -> {
// return o1.getWeight().compareTo(o2.getWeight());
//});
//
Lambda表达式简写
lambda表达式
//list.sort((o1,o2) ->o1.getWeight().compareTo(o2.getWeight()));
//
再简写
//list.sort(Comparator.comparing(apple -> apple.getWeight()));
//方法引用
list.sort(Comparator.comparing(Apple::getWeight));
list.forEach(System.out::println);
//复合Lambda表达式
//比较器复合
//逆序
list.sort(Comparator.comparing(Apple::getWeight).reversed()); //按重量递减排序
//根据重量的逆序排序、如果重量相同,根据颜色进行排序
list.sort(Comparator.comparing(Apple::getWeight).reversed().thenComparing(Apple::getColor));
//谓词复合 Predicate 谓词接口包括三个方法: negate、and和or,让你可以重用已有的Predicate来创建更复杂的谓词。
//去除非红的苹果
Predicate<Apple> redApple = item -> item.getColor().equals("red");
list.removeIf(redApple.negate());
//去除红色并且重量大于150的苹果
list.removeIf(redApple.and(apple -> apple.getWeight() > 150));
//去除红色并且重量大于150的苹果或绿苹果
list.removeIf(redApple
.and(apple -> apple.getWeight() > 150)
.or(apple -> apple.getColor().equals("green")));
}
}
Apple类
package com.sdut.k8.Lambdabds;
public class Apple {
private Integer weight;
private String color;
//无参构造方法
public Apple() {
}
//有参构造方法
public Apple(Integer weight, String color) {
this.weight = weight;
this.color = color;
}
//get和set方法
public Integer getWeight() {
return weight;
}
public void setWeight(Integer weight) {
this.weight = weight;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
//toString方法
@Override
public String toString() {
return "Apple{" +
"weight=" + weight +
", color='" + color + '\'' +
'}';
}
}
Stream流
创建Stream流
package com.sdut.k8.Lambdabds;
/**
*
* Stream 流
* 注意:***Stream自己不会存储元素
* ***Stream不会改变源对象
* 1.创建流
* *通过集合
* *通过数组
* *通过Stream的的静态方法of (了解)
* 2.中间操作
* 3.终端操作
*/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Stream;
public class MyTest3 {
public static void main(String[] args) {
//通过集合创建流
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("hello");
list.add("1234");
list.add("sssssss");
//创建流
Stream<String> stream = list.stream();
//终端操作
stream.forEach(System.out::println);
System.out.println("---------------------------");
//通过数组创建流
String[] arr = {"ddddd","vvvvvv","xxxxxxxx","zzz"};
Stream<String> stream1 = Arrays.stream(arr);
stream1.forEach(System.out::println);
}
}
使用Stream流
package com.sdut.k8.Lambdabds;
import java.util.ArrayList;
import java.util.Optional;
/**
* 使用流
*/
public class MyTest4 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("hello java");
list.add("hello js");
list.add("good bye");
list.add("good bye");
list.add("*****");
list.add("00000000000");
ArrayList<Person> list1 = new ArrayList<>();
list1.add(new Person("zs1", 20, "m"));
list1.add(new Person("zs3", 20, "m"));
list1.add(new Person("zs3", 20, "m"));
list1.add(new Person("zs4", 20, "m"));
list1.add(new Person("zs5", 20, "m"));
//筛选 -- filter(Predicatep) 接收lambda,从流中排除某些元素
//获取长度>5的所有字符串
list.stream().filter(item -> item.length()>5)
.forEach(System.out::println);
System.out.println("---------------------------------");
//去除重复元素 -- distinct() 筛选通过流所生成元素的hashCode()和equals()去除
list.stream().distinct().forEach(System.out::println);
System.out.println("----------------------------------");
list1.stream().distinct().forEach(System.out::println);
System.out.println("----------------------------");
//截断流 使元素不超过给定数量 limit(long maxSize)
list1.stream().limit(3).forEach(System.out::println);
System.out.println("-----------------------------");
//跳过元素 返回一个扔掉前n个元素的流 skip(long n)
list1.stream().skip(3).forEach(System.out::println);
//映射
// 打印字符串的长度
//list.stream().forEach(item -> System.out.println(item.length()));
//String --->int 字符串的长度 流内元素的改变(不是改变原本的流而是生成了新的流)
list.stream().map(item->item.length())
.forEach(System.out::println);
System.out.println("------------------------------------");
//打印每个person的姓名
list1.stream().map(item -> item.getName()).forEach(System.out::println);
System.out.println("--------------------------------------");
//查找和匹配
/**
* anyMatch(Predicate<? super T> predicate) 流中是否有一个元素能匹配给定的谓词
* allMatch(Predicate<? super T> predicate) 流中的元素是否都能匹配给定的谓词
* noneMatch(Predicate<? super T> predicate) 流中没有任何元素与给定的谓词匹配
* findFirst() 返回当前流中的第一个元素
* findAny() 返回当前流中的任意元素
*/
//判断list集合中的字符串是否存在长度大于5的字符串
System.out.println(list.stream().anyMatch(item ->item.length()>5));//true
//判断list集合中的字符串是否都长度大于5
System.out.println(list.stream().allMatch(item ->item.length()>5 ));//false
//判断list集合中的字符串是否没有长度大于100的元素
System.out.println(list.stream().noneMatch(item -> item.length() > 100));//true
System.out.println("------------------------------------------");
//返回流中的第一个元素
System.out.println(list.stream().findFirst().get());
//归约 通过归约操作将Stream流变成一个别的类型的值 reduce()
//计算所有的字符串长度的和
//Integer sum = list.stream().map(item -> item.length()).reduce(0, (l1, l2) -> l1 + l2);
Integer sum = list.stream().map(item -> item.length()).reduce(0, Integer::sum);
System.out.println(sum);
System.out.println("----------------------------------");
///*
// 为什么它返回一个Optional<Integer>呢?
// 考虑流中没有任何元素的情况。 reduce操作无法返回其和,因为它没有初始值。
// */
//Optional<Integer> sum1 = list.stream().map(item -> item.length()).reduce((l1, l2) -> l1 + l2);
Optional<Integer> sum1 = list.stream().map(item -> item.length()).reduce(Integer::sum);
System.out.println(sum1.get());
System.out.println("------------------------------------------");
//求字符串长度的最大值
Integer maxLength = list.stream().map(item -> item.length()).reduce(list.get(0).length(), Integer::max);
System.out.println(maxLength);
//求最小值同理 jiangmax换成min
Integer minLength = list.stream().map(item -> item.length()).reduce(list.get(0).length(), Integer::min);
System.out.println(minLength);
System.out.println("---------------------------------------------");
//集合map和reduce计算字符串的数量
Integer count = list.stream().map(item -> 1).reduce(0, Integer::sum);
System.out.println("字符串的数量:" +count);
System.out.println("---------------------------------------");
//自然排序
list.stream().sorted().forEach(System.out::println);
System.out.println("----------------------------------------");
list.stream().sorted((o1,o2) -> (o1.length() - o2.length())).forEach(System.out::println);
}
}
Person类
package com.sdut.k8.Lambdabds;
import java.util.Objects;
public class Person {
private String name;
private Integer age;
private String gender;
public Person() {
}
public Person(String name, Integer age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
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;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return Objects.equals(name, person.name) && Objects.equals(age, person.age) && Objects.equals(gender, person.gender);
}
@Override
public int hashCode() {
return Objects.hash(name, age, gender);
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
}
Stream终端操作
package com.sdut.k8.Lambdabds;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
public class MyTest5 {
public static void main(String[] args) {
/**
* Stream终端操作--collect收集
*/
//创建集合
ArrayList<String> list = new ArrayList<>();
list.add("1111");
list.add("*****");
list.add("abc");
list.add("HHHHHHHHHH");
list.add("QQQqq");
long count = list.stream().count();
System.out.println(count);
System.out.println("-------------------------------");
Optional<String> max = list.stream().max((s1, s2) -> s1.length() - s2.length());
System.out.println(max.get());
System.out.println("-------------------------------");
//将list集合中所有元素的长度保存在一个新的List中
List<Integer> list1 = list.stream()
.map(item -> item.length())
.collect(Collectors.toList());
list1.forEach(System.out::println);
System.out.println("-------------------------------");
//将list集合中所有元素的长度保存在一个新的Set中
Set<Integer> set = list.stream()
.map(item -> item.length())
.collect(Collectors.toSet());
System.out.println(set);
}
}
汇总
综合练习
-
找出2011年发生的所有交易,并按交易额排序(从低到高)。
-
交易员都在哪些不同的城市工作过?
-
查找所有来自于剑桥的交易员,并按姓名排序。
-
返回所有交易员的姓名字符串,按字母顺序排序。
-
有没有交易员是在米兰工作的?
-
打印生活在剑桥的交易员的所有交易额。
-
所有交易中,最高的交易额是多少?
-
找到交易额最小的交易。
创建两个类 – Trader交易员和Transaction交易
public class Trader { private final String name; private final String city; public Trader(String n, String c){ this.name = n; this.city = c; } public String getName() { return name; } public String getCity() { return city; } @Override public String toString() { return "Trader{" + "name='" + name + '\'' + ", city='" + city + '\'' + '}'; } }
public class Transaction {
private final Trader trader;
private final int year;
private final int value;
public Transaction(Trader trader, int year, int value){
this.trader = trader;
this.year = year;
this.value = value;
}
public Trader getTrader() {
return trader;
}
public int getYear() {
return year;
}
public int getValue() {
return value;
}
@Override
public String toString() {
return "Transaction{" +
"trader=" + trader +
", year=" + year +
", value=" + value +
'}';
}
}
package com.sdut.k8.Lambdabds.lianxi;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
public class MyTest {
public static void main(String[] args) {
Trader raoul = new Trader("Raoul", "Cambridge");
Trader mario = new Trader("Mario","Milan");
Trader alan = new Trader("Alan","Cambridge");
Trader brian = new Trader("Brian","Cambridge");
List<Transaction> list = Arrays.asList(
new Transaction(brian, 2011, 300),
new Transaction(raoul, 2012, 1000),
new Transaction(raoul, 2011, 400),
new Transaction(mario, 2012, 710),
new Transaction(mario, 2012, 700),
new Transaction(alan, 2012, 950)
);
/**
* (1) 找出2011年发生的所有交易,并按交易额排序(从低到高)。
* (2) 交易员都在哪些不同的城市工作过?
* (3) 查找所有来自于剑桥的交易员,并按姓名排序。
* (4) 返回所有交易员的姓名字符串,按字母顺序排序。
* (5) 有没有交易员是在米兰工作的?
* (6) 打印生活在剑桥的交易员的所有交易额。
* (7) 所有交易中,最高的交易额是多少?
* (8) 找到交易额最小的交易。
*/
//找出2011年发生的所有交易,并按交易额排序(从低到高)
list.stream().filter(item->item.getYear()==2011)
//.sorted((o1,o2)->o1.getValue()-o2.getValue())
.sorted(Comparator.comparing(Transaction::getValue))
.forEach(System.out::println);
System.out.println("---------------------------------");
//交易员都在哪些不同的城市工作过?
list.stream().map(item->item.getTrader().getCity())
.distinct()
.forEach(System.out::println);
System.out.println("-----------------------------------");
//查找所有来自于剑桥的交易员,并按姓名排序。
list.stream().map(item->item.getTrader())
.filter(item->item.getCity().equals("Cambridge"))
.distinct().forEach(System.out::println);
System.out.println("-----------------------------------");
//返回所有交易员的姓名字符串,按字母顺序排序。
list.stream().map(item ->item.getTrader().getName())
.distinct()
.sorted().forEach(System.out::println);
System.out.println("-----------------------------------");
//有没有交易员是在米兰工作的?
System.out.println(list.stream()
.anyMatch(item -> item.getTrader().getCity().equals("Milan")));
System.out.println("-----------------------------------");
//打印生活在剑桥的交易员的所有交易额。
Integer sum = list.stream().filter(item -> item.getTrader().getCity().equals("Cambridge"))
.map(item -> item.getValue())
.reduce(0, (n1, n2) -> n1 + n2);
System.out.println(sum);
System.out.println("-----------------------------------");
//所有交易中,最高的交易额是多少?
Optional<Integer> max = list.stream().map(item -> item.getValue())
.distinct()
.reduce(Integer::max);
System.out.println(max.get());
System.out.println("-----------------------------------");
//找到交易额最小的交易。
Integer min = list.stream().map(item -> item.getValue())
.distinct()
.reduce(Integer::min).get();
System.out.println(min);
System.out.println("-----------------------------------");
}
}
.reduce(0, (n1, n2) -> n1 + n2);
System.out.println(sum);
System.out.println("-----------------------------------");
//所有交易中,最高的交易额是多少?
Optional<Integer> max = list.stream().map(item -> item.getValue())
.distinct()
.reduce(Integer::max);
System.out.println(max.get());
System.out.println("-----------------------------------");
//找到交易额最小的交易。
Integer min = list.stream().map(item -> item.getValue())
.distinct()
.reduce(Integer::min).get();
System.out.println(min);
System.out.println("-----------------------------------");
}
}