JDK7
try-catch 支持处理多异常
try{ ...; }catch( Exc | Exc ){ //一个catch 捕获多个异常,字节码文件跟小 }
数字类型 支持下划线
int num = 123_345; float num2 = 222+33F; long num3 = 123_000_111L;
switch 支持 string
switch(){ case "java": break; ....; default: break; }
JDK8
Lambda 表达式 函数式接口
表示行为 传递的一种方式,代替匿名内部类
(参数)-> 函数主体
函数式接口
只有一个抽象方法
@FunctionalInterface
用在接口上
表示此接口会生成一个函数式接口
@FunctionalInterface public interface aa{ String go(); }
不符合要求 编译器会报错
java自带的 函数式接口
@FunctionalInterface public interface Predicate<T>{ boolean test(T t); } public static <T> List<T> filter(List<T> list , Predicate<T> p){ List<T> resuts = new ArrayLsit<>(); for(T s: list){ if(p.test(s)){ results.add(s); } } return results; } Predicate<String> nonEmptyStringPredicate = (String s) -> !s.isEmpty();
——————————————————————————
@FunctionalInterface public interface Consumer<T>{ void accept(T t); } public static <T> void forEach(list,Consumer<T> c) { for(T i: list){ c.accept(i); } } //Lambda 是 Consumer 中 accept方法的实现 forEach(Arrays.asList(1,2,3,4,5),(Integer i) -> System,out.println(i) );
————————————————
类型转换 入参T 出参R
@FunctionalInterface public interface Function<T,R>{ R apply(T t); } public static <T,R> List<R> map(List<T> list, Function<T,R> f){ List<R> result = new ArrayList<>(); for(T s:list){ result.add(f.apply(s)); } return result; } //[7,2,6] //lambda是 Function 接口的 apply方法实现 List<Intefer> 1 =map(Arrays.asList("lambdas","in","action"),(String s)-> s.length());
——————————————————
使用
//断言 void predicate(){ Predicate<String> namesStartingWithS = name -> name.startsWith("s"); boolean hello = namesStartingWithS.test("Hello"); //false } //消费数据 void consumer(){ Consumer<String> messageConsumer = message -> System.out.println(message); messageConsumer.accept("Learn java8"); //Learn java8 } //转换 void function(){ Function<String ,String> toUpperCase = name -> name.toUpperCase(); toUpperCase.apply("java"); //java } //提供数据 void supplier(){ Supplier<String> uuidGenerator =() -> UUID.randomUUID().toString(); System.out.println(uuidGenerator.get());//输出一个 UUID }
::
构造器引用
//构造器引用 Supplier<FunctionalDemo> obj = FunctionalDemo :: new; FunctionalDemo f = obj.get();
数组引用
//数组引用 Function<Integer , String[]> fun = x->new String[x]; String[] strs = fun.apply(10); System.out.println(strs.length); Function<Integer , String[]> fun1 =String[]::new; strs = fun1.apply(10); System.out.println(strs.length);
异常,函数式接口都不运行抛出 受检异常
Exception 就是受检异常
RuntimeException
如果出现这类异常,包装处理
Function<BufferedReader ,String> f = (BufferedReader b)->{ try { return b.readLine(); }catch (IOException e){ e.printStackTrace();//输出包装栈信息 throw new RuntimeException(e); } };
默认方法- 接口 default
-
类中的方法 优先级最高,类或父类中声明的方法的优先级高于任何声明为默认方法的优先级。
定义一个接口
interface A{ int add(); int deleete(); //defaul 修饰的一个默认方法, 不需要实现类全部实现 default int mod(int a,int b){ return a%b; } } //调用, 不需要有实现类 实现default 的实现,可以直接调用 void main(){ ... a = new A(); int c = a.mod(a,b); } //声明一个 空 opttiona Optional<Object> empty = Optional.empty(); //依赖一个非空的 Optional Optional<FunctionalDemo> functionalDemo = Optional.of(new FunctionalDemo()); //可以接收null 的 Optional Optional<FunctionalDemo> functionalDemo1 = Optional.ofNullable(new FunctionalDemo());
接口静态方法
interface A{ static A getA(){ return new A实现类(); } }
Optional 干掉空指针
public class UserBO{ private AddUser user; //对象可能空指针 private Optional<AddUser> optUser; //对象可以为空, 但不是null } void main(){ //声明一个 空 opttiona Optional<Object> empty = Optional.empty(); //依赖一个非空的 Optional 不会出现非空异常 Optional<FunctionalDemo> functionalDemo = Optional.of(new FunctionalDemo()); //可以接收null 的 Optional Optional<FunctionalDemo> functionalDemo1 = Optional.ofNullable(new FunctionalDemo()); }
-
Optional 类支持多种方法, map,flatMap,filter.limite
List<Project> projects = Project.buildDate(); List<String> names =projects.stream() .filrer(p->p.getStars()>1000) //筛选 star大于1000的项目 .map(Project::getName) //提取项目名称 .limit(3) .collect(Collectors.toList()); //将名称保存在List中 System.out.println(names);
Steram
-
流
-
集合与流
-
List<String> names = projects.stream() //建立操作流水线 .filter(p-> p.getStars() >1000) //筛选出 star 比较高的香 .map(Project::getName) //获取项目名称 .limit(3) //只选前3个 .conllect(Conllectors.toList()); //结果保存在另一个 List中
-
-
-
内部迭代,外部迭代
-
中间操作,终端操作
-
-
流是"从支持数据处理操作的源生成一系列的元素"
-
流利用内部迭代:丢带通过filter、map、sorted等操作
-
流操作有两类:中间操作和终端操作
-
filter和map等中间操作会返回一个流,可以用它们来设置一条流水线
-
forEach和count等终端操作返回一个非流的值
-
流中的元素按需计算的
Stream API
-
创建流 Stream.of Arrays.Stream
-
//集合 创建流对象 List<String> list = Arrays.asList("hello", "world"); Stream<String> stream = list.stream();
-
//数组创建流对象 String[] names = {"chaim","peter","john"}; Stream<String> stream1 = Arrays.stream(names);
-
//值 Stream<String> aa = Stream.of("aa", "bbb", "cc");
-
//文件流 try (Files.lines(Paths.get("文件路径"), Charset.defaultCharset())){ //操作 }catch (IOException e){ }
-
// iterator 创建无限流 Stream.iterate(0,n-> n+2) .limit(10) .forEach(System.out::println);
-
-
筛选 filter limit distinct skip
-
// filter 筛选 接收一个lambda表达式作为参数,该表达式返回boolean 在执行过程中,流将该元素注意输送给filter,并筛选出执行结果为true的元素 List<Object> result = list.stream() .filter()//( aa::isNull)筛选条件 .collect(Collectors.toList());
-
//distinct 去重 Stream<Integer> number = Stream.of(1, 2, 2, 3); number.distinct().forEach(n->System.out.println(n));//1,2,3
-
//limit 截取 Stream<Integer> number1 = Stream.of(1, 2, 2, 3); number1.distinct().limit(2).forEach(n->System.out.println(n));//1,2
-
//skip 跳过 Stream<Integer> number2 = Stream.of(1, 2, 2, 3); number2.distinct().skip(2).forEach(n->System.out.println(n));//2,3
-
-
映射 map flatMap
-
匹配 anyMatch allMatch noneMatch findAny findFirst
-
anyMacth 判断流中是否存在至少一个元素满足指定条件,这个条件通过Lambda表达式传递给anyMatch,执行结果为 boolean类型,如,判断是都所有人都是学生
boolean result = list.stream() .anyMatch(Person::isStudent);
-
allMatch 判断流中的所有元素是否都满足指定条件,这个判断条件通过Lambda表达式传递给anyMatch,执行结果为boolean类型,如,判断所有是否都是学生
boolean result = list.stream() .allMatch(Person::isStudent);
-
noneMatch 是否未匹配所有元素 流中的所有元素都不满足条件
boolean result = list.stream() .noneMatch(Person::isStudent);
-
findAny 获取任一元素 从流中随机选出一个元素来,返回一个Optional类型元素
Optional<Person> person =list.stream().findAny();
-
findFirst 获取第一个元素
Optional<Person> person =list.stream().findFirst();
-
-
归约 reduce
-
归约是将集合中的所有元素经过指定运算,折叠成一个元素输出,如 最值,平均值,这些操作都是将集合的的元素折叠成一个元素输出
-
reduce 实现归约 这个函数接收两个参数 1.初始值 2.进行归约操作的Lambda表达式
//计算所有人的年龄总和 int age = list.stream().reduce(0,(person1,person2)->person1.getAge()+pesrson2.getAge());
-
-
数值流 lntStream LongStream DoublieStream
-
采用reduce 进行数值操作会涉及到基本数据类型和引用数据类型之间的装箱,拆箱操作,因此效率比较低,当流操作为纯数值操作时,使用数值流能获得较高的效率
-
StreamAPI提供了 三种方法 mapToint 、mapToDoubile 、mapToLong
IntStream stream = list.stream().mapToInt(Person::getAge);
-
Collectors
maxBy 求最值
Optional<aa> collect = aa.stream() .collect(maxBy(Comparator.comparingInt(aa::getStars)));
sumingInt 求和
Optional<aa> collect = aa.stream() .collect(sumingInt(aa::getStats));
averaginInt 求平均
Optional<aa> collect = aa.stream() .collect(averagingInt(Comparator.comparingInt(aa::getStars)));
joining 连接字符
String.of("hello","java8") .collect(joining("=")); //结果 hello=java8
tream 操作
流创建在数据源上的,java.util.Collection 、list 集合和set集合都是数据源的一种产生的流可以是串行的,也可是并行的。通过集合类的Stream方法可以产生串行流,parallelStream 方法可以产生并行流
Stream支持的主要连续操作如下
-
filter: 接受一个 predicate 来过滤流中的所有元素
-
sorted: 返回流中已排序版本
-
map: 通过指定的函数将流中的每一个元素转变为另外的对象
-
flatMap: 每个元素沌河得到的是Stream 对象,会把子Stream 中的元素压缩到父集合
-
peek: 生成一个包含原Stream 的所有元素的新 Stream
-
limit: 生成一个包含原Stream 进行截断操作
-
skip: 返回一个丢弃原Stream 的前N 个元素后剩下元素组成的新 Stream
-
reduce: 使用指定的函数对流中元素实施消减,返回一个包括所有被元素消减元素的Optional
-
collect: 把流中的元素聚合到其他数据结构中
-
match :anyMatch、allMatch 等各种匹配操作可以用来检测是否某种 predicate 和流中元素相匹配
-
count : 返回流中的元素数量
-
findFirst: 返回Stream中的第一个元素
-
max和min: 使用给定的比较器(Operator),返回Stream 中的最大值\最小值
注意:使用Stram需要关注
-
流并不存储值,它只是某数据源的一个视图,对流的操作会产生一个结果,但流的数据源不会被修改
-
使用stream 时,要遵循先做filte 在map 原则
-
多数Stream 操作(包括 filter 、 映射map 、排序 sorted 以及去重 distinct ) 都以惰性方式实现
-
不同于其他 Stream 操作,flatMap 不是惰性计算
-
Stream 只能被 "消费" 一次,一旦遍历过就会失效
-
慎重使用并行Stream ,其底层使用的是 ForkJoinPool 的commonPool 。在不做任何配置的情况下,所有并行流都共用同一个线程池(默认线程数为机器CPU 数目,可通过系统属性 java.util.concurrent.ForkJoinPool.common.parallelism 设置 ),而且此线程池还会被其他机制依赖
并行流
直接list调用 parallel方法
list.stream() .parallel()
时间日期API
Date和Calendar 不是线程安全的,需要编写额外的代码来处理线程安全问题
-
Zoneld : 时区ID 用来确定Instant 和 LoaclDateTime 互相转换的规则
-
//获取系统默认时区 ZoneId zoneId = ZoneId.systemDefault(); ZoneId shanghai = ZoneId.of("Asia/Shanghai"); //TimeZone 转换为 ZoneId ZoneId zoneId1 = TimeZone.getDefault().toZoneId();
-
-
Instant: 用来表示时间线上的一个点
-
LocalDate 表示没有时区的日期,LocalDate 是不可变并且线程安全的
-
LocalTime 表示没有时区时间,LocalTime是不可变且线程安全的
-
LocalDateTime 表示没有时区的日期时间,LocalDateTime 是不可变并且先安全的
-
Clock 用于访问当前时刻,日期,用到的时区
CompletableFuture
-
创建 CompletableFunture
-
处理计算结果
-
转换结果
-
异常处理
-
消耗型
-
组合 Either
-
allOf anyOf
Map 增强改动
Map <String,String> map = new HashMap<>(); map.putIfAbsent("1","a"); map.forEach((k,v) - > { System.out.println(k+v); }); map.computeIfAbsent("2",e -> e+ "1"); map.computeIfPresent("1",(k,v) -> k+v ); map.remove("1" ,"a"); map.getOrDefault("2","b"); map.merge("1","a",(k,v) -> k+v );
-
putlfAbsent: 当key 没哟对应的value 时才放入新的值,可以防止旧值被覆盖
-
forEach: 方便对 map做遍历
-
computelfAbsent: 当key 没有对应的value 时才计算生成的新值
-
computelfPresent: 当key 有对应的value ,使用key 和value 生成新的 value
-
remove(k,v): 仅当k 对应的value 等于v 时,才会删除k
-
getOrDefault: 获取不到值时使用传入的默认值
-
merge: 如果key 对应的值存在,那么将对应的value 和传入的value使用后的函数并合作为新值,否则设置传入的value