java8语法

Lambda表达式

1、Lambda语法

在这里插入图片描述

2、Lambda使用

使用前:

Comparator<Apple> byWeight = new Comparator<Apple>() { 
  public int compare(Apple a1, Apple a2){ 
 	return a1.getWeight().compareTo(a2.getWeight()); 
  } 
}

使用后:

Comparator<Apple> byWeight = 
 (Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());
3、函数式接口

只定义一个抽象方法的接口,函数式接口带有@FunctionalInterface标注

函数式接口函数描述符
PredicateT->boolean
ConsumerT->void
Function<T,R>T->R
Supplier()->T
UnaryOperatorT->T
BinaryOperator(T,T)->T
BiPredicate<L,R>(L,R)->boolean
BiConsumer<T,U>(T,U)->void
BiFunction<T,U,R>(T,U)->R
4、函数式接口例子
使用案例lambda表达式函数式接口
布尔表达式(List list) -> list.isEmpty()Predicate<List>
创建对象() -> new Apple(10)Supplier
消费一个对象(Apple a) -> System.out.println(a.getWeight())Consumer
从一个对象中选择/提取(String s) -> s.length()Function<String, Integer>或ToIntFunction
合并两个值(int a, int b) -> a*bIntBinaryOperator
比较两个对象(Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight())Comparator或BiFunction<Apple, Apple,Integer>或 ToIntBiFunction<Apple,Apple>

方法引用

1、指向静态方法的方法引用
Integer::parseInt
2、指向任意类型实例方法的方法引用
String::length //String的length方法
3、指向现有对象的实例方法的方法引用
expensiveTransaction::getValue //() -> expensiveTransaction.getValue()

构造函数引用

1、不带参数构造函数
Supplier<Apple> c1 = Apple::new;
Apple a1 = c1.get();

// 等价于:

Supplier<Apple> c1 = () -> new Apple();
Apple a1 = c1.get();
2、带参数构造函数
Function<Integer,Apple> c2 = Apple::new;
Apple a2 = c2.get(110);

// 等价于:

Function<Integer,Apple> c2 = (weight) -> new Apple(weight);
Apple a2 = c2.get(110);

复合Lambda表达式

1、比较器复合
1.1 逆序
inventory.sort(Comparator.comparing(Apple::getWeight).reversed()); //按重量递减
1.2 比较器链
inventory.sort(comparing(Apple::getWeight) 
 .reversed() 
 .thenComparing(Apple::getCountry));  //重量一样时根据另一属性排序
2、谓词复合
2.1 非
Predicate<Apple> notRedApple = redApple.negate(); //redApple的非
2.2 与
Predicate<Apple> redAndHeavyApple = 
    redApple.and(a -> a.getWeight() > 150); //重150以上的红苹果
2.3 或
Predicate<Apple> redAndHeavyAppleOrGreen = 
 redApple.and(a -> a.getWeight() > 150) 
 .or(a -> "green".equals(a.getColor()));
3、函数复合
3.1 andThen
Function<Integer, Integer> f = x -> x + 1; 
Function<Integer, Integer> g = x -> x * 2; 
Function<Integer, Integer> h = f.andThen(g); 
int result = h.apply(1); //等价于g(f(x)),先执行f,再执行g
3.2 compose
Function<Integer, Integer> f = x -> x + 1; 
Function<Integer, Integer> g = x -> x * 2; 
Function<Integer, Integer> h = f.compose(g);
int result = h.apply(1); //等价于f(g(x)),先制行g,再执行f

流操作

1、中间操作
操作类型返回类型操作参数
filter中间StreamPredicate
map中间StreamFunction<T,R>
limit中间Stream
sorted中间StreamComparator
distinct中间Stream
2、终端操作
操作类型目的
forEach终端消费流中的每个元素并对其应用Lambda。这一操作返回void
count终端返回流中元素的个数。这一操作返回long
collect终端把流归约成一个集合,比如List、Map甚至是Integer

使用流

1、筛选
List<Dish> vegetarianMenu = menu.stream() 
 .filter(Dish::isVegetarian) 
 .collect(toList()); //谓词筛选
List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4); 
numbers.stream() 
 .filter(i -> i % 2 == 0) 
 .distinct() 
 .forEach(System.out::println); //过滤重复
2、截断
List<Dish> dishes = menu.stream() 
 .filter(d -> d.getCalories() > 300) 
 .limit(3) 
 .collect(toList()); //该方法会返回一个不超过给定长度的流
3、跳过
List<Dish> dishes = menu.stream() 
 .filter(d -> d.getCalories() > 300) 
 .skip(2) 
 .collect(toList()); //返回一个扔掉了前n个元素的流。如果流中元素不足n个,则返回一个空流
4、映射
List<String> dishNames = menu.stream() 
 .map(Dish::getName) 
 .collect(toList()); //方法引用Dish::getName传给了map方法,来提取流中菜肴的名称
List<String> words = Arrays.asList("Java 8", "Lambdas", "In", "Action"); 
List<Integer> wordLengths = words.stream() 
 .map(String::length) 
 .collect(toList());  //获取单词长度
5、流扁平化
List<String> uniqueCharacters = 
 words.stream() 
 .map(w -> w.split("")) 
 .flatMap(Arrays::stream) 
 .distinct() 
 .collect(Collectors.toList()); // 给定单词列表["Hello","World"],返回["H","e","l", "o","W","r","d"]
6、匹配
boolean isHealthy = menu.stream() 
 .allMatch(d -> d.getCalories() < 1000); //匹配所有元素
boolean isHealthy = menu.stream() 
 .noneMatch(d -> d.getCalories() >= 1000); //未匹配所有元素
7、查找
Optional<Dish> dish = 
 menu.stream() 
 .filter(Dish::isVegetarian) 
 .findAny(); //查找一道素食菜肴
8、归约
int sum = numbers.stream().reduce(0, (a, b) -> a + b); //元素求和
int sum = numbers.stream().reduce(0, Integer::sum);
Optional<Integer> sum = numbers.stream().reduce((a, b) -> (a + b));
Optional<Integer> max = numbers.stream().reduce(Integer::max); //最大值
Optional<Integer> min = numbers.stream().reduce(Integer::min); //最小值
9、汇总
int totalCalories = menu.stream().collect(summingInt(Dish::getCalories)); //求和
double avgCalories = 
 menu.stream().collect(averagingInt(Dish::getCalories)); //求平均值
IntSummaryStatistics menuStatistics = 
 menu.stream().collect(summarizingInt(Dish::getCalories)); //返回总和、平均值、最大最小值
10、分组
Map<Dish.Type, List<Dish>> dishesByType = 
 menu.stream().collect(groupingBy(Dish::getType));
11、多级分组
Map<Dish.Type, Map<CaloricLevel, List<Dish>>> dishesByTypeCaloricLevel = 
menu.stream().collect( 
 groupingBy(Dish::getType, 
 groupingBy(dish -> { 
 if (dish.getCalories() <= 400) return CaloricLevel.DIET; 
 else if (dish.getCalories() <= 700) return CaloricLevel.NORMAL; 
 else return CaloricLevel.FAT; 
 } ) 
 ) 
);
12、分区
Map<Boolean, List<Dish>> partitionedMenu = 
 menu.stream().collect(partitioningBy(Dish::isVegetarian));

创建流

1、数值流
int calories = menu.stream() 
 .mapToInt(Dish::getCalories) 
 .sum(); //映射到数值流
IntStream intStream = menu.stream().mapToInt(Dish::getCalories); 
Stream<Integer> stream = intStream.boxed(); //转换为对象流
IntStream evenNumbers = IntStream.rangeClosed(1, 100) 
 .filter(n -> n % 2 == 0); //表示范围[1,100],生成1到100的偶数流
IntStream evenNumbers = IntStream.range(1, 100) 
 .filter(n -> n % 2 == 0); //表示范围[1,99],生成1到99的偶数流
2、创建流
Stream<String> stream = Stream.of("Java 8 ", "Lambdas ", "In ", "Action"); //值创建流
int[] numbers = {2, 3, 5, 7, 11, 13}; 
int sum = Arrays.stream(numbers).sum(); //数组创建流
Stream.iterate(0, n -> n + 2) 
 .limit(10) 
 .forEach(System.out::println); //函数生成流,依赖前一个元素

Stream.generate(Math::random) 
 .limit(5) 
 .forEach(System.out::println); //函数生成了,不依赖前一个元素
try(Stream<String> lines = 
 Files.lines(Paths.get("data.txt"), Charset.defaultCharset())){ 
uniqueWords = lines.flatMap(line -> Arrays.stream(line.split(" ")))
 .distinct() 
 .count(); 
} 
catch(IOException e){ 
 
} //文件生成流

并行流

Stream.iterate(1L, i -> i + 1) 
 .limit(n) 
 .parallel() 
 .reduce(0L, Long::sum);

Fork-Join并行任务

public class ForkJoinSumCalculator extends RecursiveTask<Long> {

    private final long[] numbers;
    private final int start;
    private final int end;

    public ForkJoinSumCalculator(long[] numbers) {
        this(numbers, 0, numbers.length);
    }

    public ForkJoinSumCalculator(long[] numbers, int start, int end) {
        this.numbers = numbers;
        this.start = start;
        this.end = end;
    }

    public static final long THRESHOLD = 10_000;

    @Override
    protected Long compute() {
        int length = end - start;
        if(length <= THRESHOLD){
            return computeSequentially();
        }
        ForkJoinSumCalculator leftTask =
                new ForkJoinSumCalculator(numbers, start, start+length/2);
        leftTask.fork();
        ForkJoinSumCalculator rightTask =
                new ForkJoinSumCalculator(numbers, start+length/2, end);
        long rightResult = rightTask.compute();
        long leftResult = leftTask.join();

        return leftResult + rightResult;
    }

    private Long computeSequentially() {
        long sum = 0;
        for(int i=start; i<end; i++){
            sum += numbers[i];
        }
        return sum;
    }

    public static long forkJoinSum(long n){
        long[] numbers = LongStream.rangeClosed(1, n).toArray();
        ForkJoinTask<Long> task = new ForkJoinSumCalculator(numbers);
        return new ForkJoinPool().invoke(task);
    }
}

Optional使用

创建Optional对象
1、声明一个空的optional
Optional<Car> optCar = Optional.empty();
2、依据一个非空值创建Optional
Optional<Car> optCar = Optional.of(car);
3、可接受null的Optional
Optional<Car> optCar = Optional.ofNullable(car);
map从Optional对象中提取和转换值
Optional<Insurance> optInsurance = Optional.ofNullable(insurance);
Optional<String> name = optInsurance.map(Insurance::getName);
floatMap链接Optional对象
public String getCarInsuranceName(Optional<Person> person) { 
 return person.flatMap(Person::getCar) 
 .flatMap(Car::getInsurance) 
 .map(Insurance::getName) 
 .orElse("Unknown"); 
}
public Optional<Insurance> nullSafeFindCheapestInsurance( 
 Optional<Person> person, Optional<Car> car) { 
 return person.flatMap(p -> car.map(c -> findCheapestInsurance(p, c))); 
}
对Optional对象过滤
public String getCarInsuranceName(Optional<Person> person, int minAge) { 
 return person.filter(p -> p.getAge() >= minAge) 
 .flatMap(Person::getCar) 
 .flatMap(Car::getInsurance) 
 .map(Insurance::getName) 
 .orElse("Unknown"); 
}

CompletableFuture异步编程

使用异步api
public Future<Double> getPriceAsync(String product) {
 CompletableFuture<Double> futurePrice = new CompletableFuture<>(); 
 new Thread( () -> { 
 double price = calculatePrice(product); 
 futurePrice.complete(price); 
 }).start(); 
 return futurePrice; 
}
使用工厂方法创建
public Future<Double> getPriceAsync(String product) { 
 return CompletableFuture.supplyAsync(() -> calculatePrice(product)); 
}
使用定制执行器
private final Executor executor = 
 Executors.newFixedThreadPool(Math.min(shops.size(), 100), 
 new ThreadFactory() { 
 public Thread newThread(Runnable r) { 
 Thread t = new Thread(r); 
 t.setDaemon(true); 
 return t; 
 }
});

CompletableFuture.supplyAsync(() -> shop.getName() + " price is " + 
 shop.getPrice(product), executor);
构造异步操作
public List<String> findPrices(String product) { 
 List<CompletableFuture<String>> priceFutures = 
     shops.stream() .map(shop -> CompletableFuture.supplyAsync( 
 		() -> shop.getPrice(product), executor)) 
 	.map(future -> future.thenApply(Quote::parse))  //thenApply执行同步操作
 	.map(future -> future.thenCompose(quote ->      //thenCompose级联操作,第一个执行完作为参数传递给第二个
 CompletableFuture.supplyAsync( () -> Discount.applyDiscount(quote), executor))).collect(toList()); 
 return priceFutures.stream().map(CompletableFuture::join).collect(toList()); 
}
// thenCombine两个CompletableFuture不需要依赖执行
异步优化
public Stream<CompletableFuture<String>> findPricesStream(String product) { 
 return shops.stream()
     .map(shop -> CompletableFuture.supplyAsync(() -> shop.getPrice(product), executor)) 
 	.map(future -> future.thenApply(Quote::parse)) 
 	.map(future -> future.thenCompose(
        quote ->CompletableFuture.supplyAsync(() -> Discount.applyDiscount(quote), executor))); 
}

CompletableFuture[] futures = findPricesStream("myPhone") 
 	.map(f -> f.thenAccept(System.out::println)) 
 	.toArray(size -> new CompletableFuture[size]); 
	CompletableFuture.allOf(futures).join();

日期时间API

LocalDate使用
LocalDate date = LocalDate.of(2014, 3, 18); 
int year = date.getYear(); 
Month month = date.getMonth();
int day = date.getDayOfMonth(); 
DayOfWeek dow = date.getDayOfWeek(); 
int len = date.lengthOfMonth();
boolean leap = date.isLeapYear();

LocalDate today = LocalDate.now();

int year = date.get(ChronoField.YEAR); 
int month = date.get(ChronoField.MONTH_OF_YEAR); 
int day = date.get(ChronoField.DAY_OF_MONTH);

LocalDate date = LocalDate.parse("2014-03-18");
LocalTime使用
LocalTime time = LocalTime.of(13, 45, 20); 
int hour = time.getHour(); 
int minute = time.getMinute(); 
int second = time.getSecond();

LocalTime time = LocalTime.parse("13:45:20");
LocalDateTime使用
LocalDate date = LocalDate.of(2014, Month.SEPTEMBER, 21);
LocalTime time = LocalTime.of(10, 1, 0);
LocalDateTime dt1 = LocalDateTime.of(2014, Month.SEPTEMBER, 21, 10, 0, 0);
LocalDateTime dt2 = LocalDateTime.of(date, time);
LocalDateTime dt3 = date.atTime(time);
LocalDateTime dt4 = date.atTime(10, 1, 0);
LocalDateTime dt5 = time.atDate(date);

LocalDate date1 = dt1.toLocalDate();
LocalTime time1 = dt1.toLocalTime();
日期解析、格式化
LocalDate date1 = LocalDate.of(2022, 11, 21);
LocalDate date2 = date1.withYear(2011);
LocalDate date3 = date2.withDayOfMonth(25);
LocalDate date4 = date3.with(ChronoField.MONTH_OF_YEAR, 9);

LocalDate date5 = LocalDate.of(2022, 11, 21);
LocalDate date6 = date5.plusWeeks(1);
LocalDate date7 = date6.minusYears(3);
LocalDate date8 = date7.plus(6, ChronoUnit.MINUTES);
TemporalAdjuster使用
import static java.time.temporal.TemporalAdjusters.*; 
LocalDate date1 = LocalDate.of(2014, 3, 18); 
LocalDate date2 = date1.with(nextOrSame(DayOfWeek.SUNDAY)); 
LocalDate date3 = date2.with(lastDayOfMonth());
方法名描述
firstDayOfMonth创建一个新的日期,它的值为当月的第一天
firstDayOfNextMonth创建一个新的日期,它的值为下月的第一天
dayOfWeekInMonth创建一个新的日期,它的值为同一个月中每一周的第几天
firstDayOfNextYear创建一个新的日期,它的值为明年的第一天
firstDayOfYear创建一个新的日期,它的值为当年的第一天
firstInMonth创建一个新的日期,它的值为同一个月中,第一个符合星期几要求的值
lastDayOfMonth创建一个新的日期,它的值为当月的最后一天
lastDayOfNextMonth创建一个新的日期,它的值为下月的最后一天
lastDayOfNextYear创建一个新的日期,它的值为明年的最后一天
lastDayOfYear创建一个新的日期,它的值为今年的最后一天
lastInMonth创建一个新的日期,它的值为同一个月中,最后一个符合星期几要求的值
next/previous创建一个新的日期,并将其值设定为日期调整后或者调整前,第一个符合指定星
nextOrSame/previousOrSame创建一个新的日期,并将其值设定为日期调整后或者调整前,第一个符合指定星
日期打印输出
LocalDate date = LocalDate.of(2014, 3, 18);
String s1 = date.format(DateTimeFormatter.BASIC_ISO_DATE); 
String s2 = date.format(DateTimeFormatter.ISO_LOCAL_DATE);

LocalDate date1 = LocalDate.parse("20140318",DateTimeFormatter.BASIC_ISO_DATE); 
LocalDate date2 = LocalDate.parse("2014-03-18", DateTimeFormatter.ISO_LOCAL_DATE);

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); 
LocalDate date1 = LocalDate.of(2014, 3, 18); 
String formattedDate = date1.format(formatter); 
LocalDate date2 = LocalDate.parse(formattedDate, formatter);

DateTimeFormatter italianFormatter = 
 DateTimeFormatter.ofPattern("d. MMMM yyyy", Locale.ITALIAN); 
LocalDate date1 = LocalDate.of(2014, 3, 18); 
String formattedDate = date.format(italianFormatter); // 18. marzo 2014 
LocalDate date2 = LocalDate.parse(formattedDate, italianFormatter);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值