-
lambda
- 局部变量必须是final(在另一线程运行lambda,将局部变量传给它运行,实质只是拷贝,若非final,根本调用不到这个变量,至于为什么必须是final,因为只是拷贝,所以无法改变)。
- 虽然看着很先进,其实Lambda表达式的本质只是一个语法糖,由编译器推断并帮你转换包装为常规的代码,因此你可以使用更少的代码来实现同样的功能。
- Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。
- 简单例子
- foreach
-
function
当做新建接口来使用,前提是这个接口只有一个方法需要override,那么可以直接用lambda表达式(args1, args2, ...)-> expression或{statements;} 等价new interface(){ @Override public xxx func(args1, args2){statements/expression}}。
- JAVA中的流式计算(好像PYTHON啊) , 先是在list中添加一些元素,然后有DEMO。 添加元素 filter使用 重用filters 使用limit
- 定义Function接口Function<String, Boolean>,相当于定义了一个函数,赋值为lambda,可以用这个来进行判定(function.apply)实际上类似consumer,只不过consumer不返回结果,而function返回结果。参考资料:http://ifeve.com/jjava-util-function-java8/
-
optional
- 意图:用于解决空指针异常的问题。
- 使用禁区
- 建议使用的方法
- Optional 的三种构造方式: Optional.of(obj), Optional.ofNullable(obj) 和明确的 Optional.empty(),当对象可为空时,使用ofNullable,否则使用of,构造时既进行null检查。
- 典型使用范式
- 使用 Optional 时尽量不直接调用 Optional.get() 方法, Optional.isPresent() 更应该被视为一个私有方法, 应依赖于其他像 Optional.orElse(), Optional.orElseGet(), Optional.map() 等这样的方法.
- https://www.cnblogs.com/woshimrf/p/java-optional-usage-note.html#_caption_2
- 目前看到的一种优雅的使用场景是 optional搭配stream能简化代码, 避免一大堆判空。Optional里调用filter等流式方法会自动进行判空。
- optional中的flatmap用于返回为optional情况,如果返回不为optional,使用map,会自动包装为optional。
- Optional使用场景: 需要对一个对象为空时做其自身的特殊处理,或是需要流式调用该对象(级联操作什么的~)。
-
枚举类
- 使用enum定义(public enum name{})
- 简单枚举类
- 使用起来像静态变量一样, 类名.枚举名直接调用
- switch中使用enum
- enum这个关键字,可以理解为跟class差不多,这也是个单独的类。可以看到,上面的例子里面有属性,有构造方法,有getter,也可以有setter,但是一般都是构造传参数。还有其他自定义方法。那么在这些东西前面的,以逗号隔开的,最后以分号结尾的,这部分叫做,这个枚举的实例。也可以理解为,class new 出来的实例对象。这下就好理解了。只是,class,new对象,可以自己随便new,想几个就几个,而这个enum关键字,他就不行,他的实例对象,只能在这个enum里面体现。也就是说,他对应的实例是有限的。这也就是枚举的好处了,限制了某些东西的范围,举个栗子:一年四季,只能有春夏秋冬,你要是字符串表示的话,那就海了去了,但是,要用枚举类型的话,你在enum的大括号里面把所有的选项,全列出来,那么这个季节的属性,对应的值,只能在里面挑。不能有其他的。
- 枚举使用规范
- ENUM类有两个默认属性(name[定义的常量名], ordinary[常量名所在的索引, 从0开始])
- 总结。。。枚举类就可以看成特殊的类, 默认有上面两个成员变量。 枚举类的特点和必须遵循的规则就是, 提供 若干个类实例(在类中定义 name(val1, val2,...)val代表其他成员变量),然后在下面再定义这些val的名字, 并且提供对应的get、set。其他还有一些默认方法比如ENUM.values()之类的看到再补充。
-
可变参数
- public void variable(int ... args) 在逻辑上等价于 public void variable(int[] args),在内部使用args是一致的。
- 在传参时候 可变参数(...)方式 既可以传数组, 也可以传(int1,int2,int3...)。 而不可变(int[] args)方式只能传数组。
- 两种写法 无法重载(表明其一致性)
- 可变参数只能在整个参数列表的最后一项(因为其具有不定性) 且 会作为重载的最弱选择项(重载 优先匹配 无可变参数函数)
-
泛型
- 泛型的实质就是编译时检查类型是否正确。在编译检查结束后,会将泛型擦除,也就是说ArrayList<Integer>、ArrayList<String>是同一个类。
- 泛型使用分为泛型接口、泛型类、泛型方法,其中接口与类比较好理解。如图: 泛型类
- 泛型方法说明如图: 泛型方法
- 还是蛮复杂的, 详见https://blog.csdn.net/s10461/article/details/53941091
- 类型绑定:正常使用泛型, 编译器是无法确定泛型的类型的,因此泛型变量只能调用Object类的方法,通过<T extends xxx>来限定T的类型,可以调用xxx的方法。作用1:限定,作用2:调用方法
- 无界通配符?:【唯一】使用场景 填充泛型变量T ?extends XXX 同上 。无界通配符和泛型T的区别就在于一个用于填充泛型变量, 一个用于定义类和方法。
- https://blog.csdn.net/qq_27093465/article/details/73249434
- 真的蛋疼, 编译完泛型就被擦除成 Object或者上界了, 一个类继承泛型类且指定泛型, 就变成了普通类
-
pair的使用
- TODO
-
Stream
- https://blog.csdn.net/wfg18801733667/article/details/52003323 参考教程
- 数据流是单体(Monad),并且在Java8函数式编程中起到重要作用。
- 对集合数据进行聚合操作的一种方式,就像数据经过一个流水线一样。
- 基于Collectioin的集合数据都可以使用Stream流、Arrays也可以调用stream流
- 支持foreach遍历数据
- 支持map 来对数据进行逐个转换
- 支持peek来对数据进行消费
- 支持filter 来对数据进行过滤(满足条件的留下)
- 支持limit 来对数据个数进行限制
- 支持sorted来对数据进行排序
- 支持collect使用收集器
- flatmap和map:flatmap用于递减层数,比如一个List<List<String>>的stream,通过flatmap可以将第二层的List<String>进行处理, 然后返回一个结果stream作为缩减层数后的新stream:List<Stream>,而map则是将各个值进行映射,处理后仍然是List<List<Stream>>。再比如LIst<User>这样,如果是调用flatmap,可以进行级联获取users.stream().flatmap(u -> u.getOrders.stream())这样来降维,使得一个stream映射到一个新的stream,原来的user流变为了orders流下一步是对每个order进行处理。而如果调用map,是将流中的每个user变为orders,下一步需要对orders进行处理。
- stream分为中间操作和终端操作,stream必须有终端操作才会执行中间操作。终端操作包括foreach,collect,sum等聚合操作。当想对stream里的元素执行某些方法后仍然返回流就必须使用中间操作,因为一旦使用终端操作,整个流就将返回结果。
-
一些方法
- ncopies
- String.join(regrex, iterable<? extends charsequence>) 将集合用某个字符连接起来。
- Collections.singletonList(xxx) 创建一个单实例的list,list的容量为1, 不可变。
-
一些类
- 使用JDK8的DateTimeFormatter(可定义全局)来替代SimpleDateFormat(线程不安全)
网友评论