Lambda
规则
1,语法格式
语法格式1:无参数,无返回值
() -> System.out.println(“hello”)语法格式2:有一个参数,无返回值,小括号可以省略不写
a -> System.out.println(a);语法格式3:多个参数 ,Lambda体中有多条语句
Comparator com = (x, y) -> {
System.out.println(“aaaa”);
return Integer.compare(x, y);
};语法格式4:有返回值,但是只有一条语句
Comparator com1 = (x,y)->Integer.compare(x, y);语法格式5:参数列表的参数类型可以省略不写
Comparator com1 = (Integer x, Integer y)->Integer.compare(x, y);可以 @FunctionalInterface注解帮我们检查一个接口是不是 函数式接口
2,内置的函数式接口
Consumer: 消费性接口
void accept(T t);Supplier: 供给型接口
T get();Function<T,R>: 函数型接口
R apply(T t);Predicate: 断言型接口
boolean test(T t);
方法引用,构造器引用,数组引用(见例子)
1,方法引用
//方法引用,若lambda体中的内容有方法已经实现了,我们可以使用方法引用。
//注意: 1,lambda体中调用方法的参数列表与返回值类型,要与函数式接口中方法的参数列表和返回值一致才行 // 1,对象::实例方法名
Consumer<String> con = (x)->System.out.println(x);
Consumer<String> con1 = System.out::println;
Supplier<String> su = employee::getName;
//2,类::静态方法名
Comparator<Integer> com = Integer::compare;
//3,类::实例方法名
BiPredicate<String, String> bp = (x,y)->x.equals(y);
//第一个参数时方法的调用者,第二个参数是方法的参数
BiPredicate<String, String> bp1 = String::equals;
2,构造器引用
//构造器引用
//ClassName::new //自动匹配对应的构造器
Supplier<Employee> su = Employee::new; //对应的无参
EmployeeConstructor ec = Employee::new; //对应的多参
interface EmployeeConstructor{
Employee get(String name, int age, double salary);
}
3,数组引用
//数组引用
//type::new
Function<Integer, String[]> fun = (x)-> new String[x];
Function<Integer, String[]> fun2 = String[]::new;
Stream编程
规则
/*
* stream操作步骤
* 1,创建流
* 通过Collection提供的stream()或者paralelStream()
* 通过Arrays.stream(array)
* 通过Stream类中的静态方法 Stream.of("aa","bb","cc")
* 创建无限流
* //迭代
* Stream.iterate(0, x->x+2)
* //生成
* Stream.generate(Math::random)
* 2,中间操作
* 会生成新流
* 2.1 筛选与切片
* filter : 从流中筛选符合条件的对象生成新流
* limit:从流中找到需要的数据前面几个值
* skip: 跳过前n个
* distinct: 去重,但是 需要生成equals和hashcode
* 2.2 映射
* map 将元素转换成其他形式或提取信息,将提取的信息转换成一个新流
* flatMap :如果获得的元素是一个流,则把这个流中元素提取出来,形成一个新流
* 2.3排序
* sorted()
*
*
* 3,中止操作
* 中止操作(只有 执行了终止操作,中间操作才会执行)
* allMatch(Predicate) 检查是否匹配所有元素
* anyMatch是否至少匹配一个元素
* noneMatch是否没有匹配所有元素
* findFirst返回第一个元素 Optional<Employee>
* findAny 返回当前流中的任意元素
* count返回流中元素的总个数
* max 返回最大值
* min 返回最小值
*
* 收集 (见test6)
*
* 顺序流,并行流
* .parallel() 底层fork join
* .sequential()
*
*optional容器类的常用方法
* 创建一个Optional实例 Optional.of(T t)
* Optional<Employee> em = Optional.of(new Employee());
* 创建一个空的Optional对象
* Optional.empty();
* Optional.ofNullable(null)//这个也可以构造不空的对象
* isPresent() :判断容器中是否有值
* orElse(T t): 不包含值,则返回传来的默认值
* orElseGet(Supplier t):
* map(Function f) : 如果有值,则返回处理后的Optional,否则返回 Optional.empty();
* flatMap(Function f)与map类似,要求f的返回值必须是Optional<R>
*/
部分测试
public class StreamTest {
List<Employee> employees = Arrays.asList(
new Employee("1",10,1000,Status.BUSY),
new Employee("2",20,2000,Status.FREE),
new Employee("3",30,3000,Status.BUSY),
new Employee("4",40,4000,Status.VOCATION),
new Employee("5",50,5000,Status.BUSY),
new Employee("5",50,5000,Status.VOCATION),
new Employee("5",50,5000,Status.FREE)
);
/*
* 2.2 映射
* map 将元素转换成其他形式或提取信息,将提取的信息转换成一个新流
* flatMap :如果获得的元素是一个流,则把这个流中元素提取出来,形成一个新流
*/
@Test
public void test2() {
List<String> list = Arrays.asList("aaa","bbb","ccc");
list.stream()
.map(str->str.toUpperCase())
.forEach(System.out::println);
employees.stream()
.map(Employee::getName)
.forEach(System.out::println);
Stream<Character> stream = list.stream()
.flatMap(StreamTest::fiterCharacter);
stream.forEach(System.out::println);
}
/*
* 归约 reduce
*/
@Test
public void test5() {
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Integer sum = list.stream()
.reduce(0,(x,y) -> x + y);
System.out.println(sum);
System.out.println("-----算一下员工工资的总和-----");
double salarySum = employees.stream()
.map(Employee::getSalary)
.reduce(0.0,(x,y)->x+y);
Optional<Double> sum2 = employees.stream()
.map(Employee::getSalary)
.reduce(Double::sum);
System.out.println(salarySum);
System.out.println(sum2.orElse(0.0));
}
/*
* 收集
*/
@Test
public void test6() {
//获得平均值,最大值,最小值,总和等
DoubleSummaryStatistics collect = employees.stream().collect(Collectors.summarizingDouble(Employee::getSalary));
collect.getAverage();
List<String> list = employees.stream()
.map(Employee::getName)
.collect(Collectors.toList());
list.forEach(System.out::println);
System.out.println("-----总数-----");
Long count = employees.stream()
.map(Employee::getName)
.collect(Collectors.counting());
System.out.println(count);
System.out.println("-----平均值-----");
double avery = employees.stream()
.collect(Collectors.averagingDouble(Employee::getSalary));
System.out.println(avery);
System.out.println("-----总和-----");
double sum = employees.stream()
.collect(Collectors.summingDouble(Employee::getSalary));
System.out.println(sum);
//最大值
//最小值
//分组 按照状态分组
Map<Status,List<Employee>> map = employees.stream().collect(Collectors.groupingBy(Employee::getStatus));
//多级分组 先按照状态分组,再按照年龄段份
Map<Status,Map<String,List<Employee>>> map1 = employees.stream()
.collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy(e->{
if(e.getAge() <= 35) return "青年";
return "老年";
})));
//分区 满足条件的一个区,不满足的另外一个区
Map<Boolean,List<Employee>> map2 =
employees.stream().collect(Collectors.partitioningBy(e-> e.getSalary() > 3000));
//连接
String str = employees.stream().map(Employee::getName).collect(Collectors.joining("-","开始标志--","结束标志"));
System.out.println(str);
}
@Test
public void test7() {
OptionalLong res = LongStream.range(0, 100000000000L)
.parallel()
.reduce(Long::sum);
System.out.println(res.orElse(1l));
}
}
部分时间API
/*
* 接口中可以有默认方法,使用default修饰
* 接口中也可以有静态方法
*
* 全新的时间API
* localDate localDateTime localTime
* .plusYears .minusYears
* 时间戳(unix元年到此时的毫秒值)
* Instant instant = Instant.now();//默认是UTC时区
* Duration 计算两个时间之间的间隔 Duration duration = Duration.between(localDate1, localDate2);
* LocalDateTime lo = LocalDateTime.now();
* DateTimeFormatter ldt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
* String str = ldt.format(lo);
*/
本文详细介绍了Java 8的Lambda表达式的使用规则,包括各种语法格式和内置的函数式接口,如Consumer、Supplier、Function和Predicate。此外,还探讨了方法引用、构造器引用和数组引用的运用。同时,文章涵盖了Stream编程的基本规则和部分测试场景,以及Java 8的时间API应用。
748

被折叠的 条评论
为什么被折叠?



