Java8新特性
函数式接口
接口中只与一个必须被重写的抽象方法
@FunctionalInterface
四大内置函数式接口:
1.消费型接口 Consumer
void accept(T t) --> 有来无回,有参数没有返回值
2.供给型接口 Supplier
T get()
3.函数型接口 Function<T,R>
R apply(T t)
4.段言型接口 Predicate
boolean test(T t)
public class FunctionalInterface {
public static void main(String[] args) {
testConsumer(5000, m-> System.out.println("今天在薇娅直播间为鸿星尔克消费"+m));
testConsumer(10000, m-> System.out.println("今天在李佳琪直播间为鸿星尔克消费"+m));
System.out.println(getNum(5,()->(int)(Math.random()*(5-1+1)+1)));;
System.out.println(getNum(3,()->(int)(Math.random()*(15-10+1)+10)));;
System.out.println(strHandler(" haha ",s->s.trim()));;
System.out.println(strHandler(" haha ",s->s.toUpperCase()));;
List<Employee> list = new ArrayList<Employee>();
System.out.println(checkEmp(list,e->e.getAge()>=18));
}
//对员工集合中的员工数据按照某种规则进行过滤,返回结果
public static List<Employee> checkEmp(List<Employee> list, Predicate<Employee> predicate){
List<Employee> newList = new ArrayList<>();
for(Employee e:list){
if(predicate.test(e)){
newList.add(e);
}
}
return newList;
}
//对字符串进行处理,返回结果
public static String strHandler(String str, Function<String,String> my){
return my.apply(str);
}
//产生指定个数的指定规则的随机数
public static List<Integer> getNum(int num, Supplier<Integer> supplier){
List<Integer> list = new ArrayList<>();
for(int i=1;i<=num;i++){
list.add(supplier.get());
}
return list;
}
//消费的功能
public static void testConsumer(int money, Consumer<Integer> con){
con.accept(money);
}
}
方法引用
当lambda体的实现,是通过调用其他方法实现的,可以通过方法引用的方式实现简化Lambda表达式
是lambda表达式的另外一种表现形式,简化Lambda表达式 ()->{}
语法: ( : : )
对象::成员方法名
1)lambda体的实现是否是通过调用了另外一个方法实现的
2)内部所引用方法的返回值是否与lambda的返回值保持一致
类名::静态方法名
类名::成员方法名
public class FunctionQuite {
public static void main(String[] args) {
test3();
}
//类名::成员方法名
public static void test3(){
//BiPredicate<String,String> pre = (x,y)-> x.equals(y);
BiPredicate<String,String> pre = String::equals;
System.out.println(pre.test("张三","张三封"));;
}
//类名::静态方法名
public static void test2(){
BiFunction<Integer,Integer,Integer> function = Math::max;
System.out.println(function.apply(100,101));;
Comparator<Integer> com = Integer::compareTo;
System.out.println(com.compare(18,18));;
}
//对象::成员方法名
public static void test1(){
List<Integer> list = List.of(1,2,3,4,5);
list.forEach(x->{
System.out.println(x);
});
PrintStream ps = System.out;
list.forEach(x->{
ps.println(x);
});
list.forEach(ps::println);
list.forEach(System.out::println);
}
}
构造器引用
类名::new
lambda体中创建了对象.引用了某一个构造器 √
所引用的构造器的参数列表是否与lambda的参数列表一致
创建的对象作为lambda返回值 数组引用
类型[]::new
public class Class003_FunctionQuite {
public static void main(String[] args) {
Supplier<Employee> sup = Employee::new;
System.out.println(sup.get();
Function<String,Employee> fun = s -> new Employee(s);
fun = Employee::new;
System.out.println(fun.apply("yinwei"));
//数组引用
Function<Integer,Integer[]> fun2 = i -> new Integer[i];
fun2 =Integer[]::new;
System.out.println(Arrays.toString(fun2.apply(5)));
}
}
class Employee{
private String name;
private int num;
public Employee() {
}
public Employee(String name) {
this.name = name;
}
public Employee(String name, int num) {
this.name = name;
this.num = num;
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", num=" + num +
'}';
}
}
Stream流:
根据数据源所产生的的元素序列
数据源: 集合,数组 —> 侧重点在数据的存储
stream流: -->关注数据的计算
特点:
1.流本身不能存储数据
2.流不能修改数据源中的数据
3.流是一次性的流,流是式操作的每一步都会返回一个持有结果的新流
4.延迟执行|惰性加载 : 当不进行终止行为时候,不会执行流式中间操作
中间操作
筛选和切片
filter-接收Lambda,从流中排除某些元素
limit-截断流,使其元素不超过给定数量
skip-跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流。
distinct-筛选,通过流所生产元素的hashCode()和equals()去除重复元素
排序
sorted(Comparable)-自然排序
sorted(Comparator)-定制排序
public class Stream {
static List<Employee> emps = Arrays.asList(
new Employee(102,"张三", 18, 3333.33),
new Employee(101,"李四", 38, 4444.44),
new Employee(104,"王五", 50, 5555.55),
new Employee(104,"王五", 50, 5555.55),
new Employee(103,"赵六", 16, 6666.66),
new Employee(105,"田七", 28, 7777.77)
);
public static void main(String[] args) {
//1.获取流
Stream<Employee> stream = emps.stream();
//2.中间操作
Stream<Employee> stream1 = stream
.filter(e->{
return e.getAge()>=18;
})
.distinct() //去重
//.limit(3)
//.skip(1)
//.sorted(); //默认根据内部比较器
.sorted((x,y)->Double.compare(y.getPrice(), x.getPrice()));
//3.终止行为
stream1.forEach(System.out::println);
}
}
映射:
map : 将stream操作的每一个元素都作用与实参传递的函数,映射一个结果,返回操作结果的流 —> *****
flatMap : 将stream操作的每一个元素都作用与实参传递的函数,映射一个结果,结果必须为一个流,最终返回所有结果流结合以后的一个流
public class map {
static List<Employee> emps = Arrays.asList(
new Employee(102,"张三", 18, 3333.33),
new Employee(101,"李四", 38, 4444.44),
new Employee(104,"王五", 50, 5555.55),
new Employee(104,"王五", 50, 5555.55),
new Employee(103,"赵六", 16, 6666.66),
new Employee(105,"田七", 28, 7777.77)
);
public static void main(String[] args) {
//1.获取流
Stream<Employee> stream = emps.stream();
//2.中间操作
//1) 获取员工姓名的流
Stream<String> stream1 = stream
.map(employee -> employee.getName())
.distinct();
List<String> list = List.of("aaa","bbb","ccc");
Stream<Character> stream2 = list.stream()
//.map(Class003_map::getCharacterStream); //[[a,a,a],[b,b,b],[c,c,c]]
.flatMap(Class003_map::getCharacterStream); //[a,a,a,b,b,b,c,c,c]
//3.终止行为
stream1.forEach(System.out::println);
//流中操作流
/*stream2.forEach(s->{
s.forEach(System.out::println);
});*/
stream2.forEach(System.out::println);
}
public static Stream<Character> getCharacterStream(String str){
//1.转为字符数组
List<Character> ls = new ArrayList<>();
for(char ch : str.toCharArray()){
ls.add(ch);
}
return ls.stream();
}
}
终止行为:
查找与匹配
收集 collect()
public class Stream {
static List<Employee> emps = Arrays.asList(
new Employee(102,"张三", 18, 3333.33),
new Employee(101,"李四", 38, 4444.44),
new Employee(104,"王五", 50, 5555.55),
new Employee(104,"王五", 50, 5555.55),
new Employee(103,"赵六", 16, 6666.66),
new Employee(105,"田七", 28, 7777.77)
);
public static void main(String[] args) {
//获取流
Stream<Employee> stream = emps.stream();
//终止行为
System.out.println(stream.allMatch(e->e.getAge()>=18));
// 需求:找到员工工资最高的员工信息
//1)按照工资做降序排序
//找到第一个
Optional<Employee> op = emps.stream().sorted((x, y)->Double.compare(y.getPrice(),x.getPrice())).findFirst();
System.out.println(op.get());
//findAny-返回当前流中的任意元素
System.out.println(emps.parallelStream().findAny().get());
System.out.println(emps.stream().parallel().findAny().get());
//count-返回流中元素的总个数
System.out.println(emps.stream().filter(e->e.getPrice()>=5000).distinct().count());
//2)max()
System.out.println(emps.stream().max((x,y)->Double.compare(x.getPrice(),y.getPrice())).get());;
//找到薪资最高的薪资值
System.out.println(emps.stream().map(Employee::getPrice).max(Double::compareTo).get());;
需求:获取当前公司所有员工的姓名添加到集合中
//toList()
List<String> list = emps.stream()
.map(Employee::getName)
.collect(Collectors.toList());
list.forEach(System.out::println);
//toSet()
Set<Double> set = emps.stream()
.map(Employee::getPrice)
.collect(Collectors.toSet());
set.forEach(System.out::println);
//toMap() System.out.println(emps.stream().distinct().collect(Collectors.toMap(Employee::getId,Employee::getName)));;
工资总和
System.out.println(emps.stream().collect(Collectors.summingDouble(Employee::getPrice)));;
}
}