JDK 8新特性
一、default关键字
jdk8开始 接口可以有方法实现了 使用default关键字修饰具体格式如下:
default void test(){
system.out.println("xxxxx");
}
静态方法 :
static void test(){
System.out.println("这是静态方法");
}
二、新增Base64 API
旧的加密方式:引入第三方jar包
缺点:编解码效率低下
新的Base 64 编解码 直接封装在了jdk 里面
void testBase64()throws Exception{
Base64.Encoder encoder = Base64.getEncoder();
String test = "小";
byte[] testbyte = encoder.encode(test.getBytes("UTF-8"));
System.out.println(new String(testbyte));
Base64.Decoder decoder = Base64.getDecoder();
byte[] bytes = decoder.decode(testbyte);
System.out.println(new String(bytes));
}
三、日期处理类
1、LocalDate、LocalTime、LocalDateTime
现在是几号 final int dayOfMonth = LocalDate.now().getDayOfMonth();
现在是周几 DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek();
现在是今年第几天 int dayOfYear = LocalDate.now().getDayOfYear();
获取当前日期的月份对象 Month month = LocalDate.now().getMonth();
第几月 int monthValue = LocalDate.now().getMonthValue();
获取当前日期的年份 int year = LocalDate.now().getYear();
格式化:
旧:线程不安全
SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
simpleDateFormat.format(new Date());
新:线程安全
final String format = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
日期处理:
LocalDate.now().plusDays(1); //日期加1
LocalDate.now().plusMonths(1); //月份加1
LocalDate.now().plusWeeks(1); //周加1
LocalDate.now().plusYears(1); //年份加1
LocalDate.now().minusDays(1); //日期减1
LocalDate.now().minusMonths(1); //月份减1
LocalDate.now().minusWeeks(1); //周减1
LocalDate.now().minusYears(1); //年份减1
boolean isBefore(ChronoLocalDate other) //是否在对象日期之前
boolean isAfter(ChronoLocalDate other) //是否在对象日期之后
计算日期时间差 Duration 类:
LocalDate.now();
LocalDateTime localDate = LocalDateTime.of(2019,11,6,10,22,30);
Duration duration = Duration.between(localDate,LocalDate.now());
duration.toDays(); //相差天数
duration.toHours(); //相差小时
四、Optional 类
作用:主要针对空指针问题
1、of(T value);
Optional <> optional = Optional.of(T value);
Integer integer = null;
Optional<Integer> optionalInteger = Optional.of(integer);
其中 value 不能为空 否则报空指针
源码:
/**
* Returns an {@code Optional} with the specified present non-null value.
*
* @param <T> the class of the value
* @param value the value to be present, which must be non-null
* @return an {@code Optional} with the value present
* @throws NullPointerException if value is null
*/
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
2、ofNullable(T value);
Integer integer = null;
//Optional<Integer> optionalInteger = Optional.of(integer);
Optional<Integer> optionalInteger = Optional.ofNullable(integer);
其中的value可以是空值 null
源码
:
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
public static<T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
private static final Optional<?> EMPTY = new Optional<>();
3、兜底方法orElse();
Integer integer = null;
Integer integer1 = 1;
Integer i = Optional.ofNullable(integer).orElse(integer1);
输出的事integer1的值
方式2、如果map映射获取学生年龄失败 则取兜底数据
student student = null;
Integer i = Optional.ofNullable(student).map(obj ->obj::getage())).orElse(6);
源码:
public T orElse(T other) {
return value != null ? value : other;
}
optional的一些使用
如果为空给定一个指定值
Optional.ofNullable(reportDao.getInventoryRecordTotalWithoutPage(recordeQuery))
.ifPresent(x -> {
BigDecimal currentTotalWeight = x.getWeight();
dataMap.put("totalWeight", currentTotalWeight);
});
如果不能确定操作对象是否为空之间使用optional 接收 然后在进行业务操作 如果需要返回 则使用兜底函数 返回一个非空的兜底数据 和电商系统熔断降级思想类似
五、lambda表达式
1>、函数式接口
1、Java 8 新特性 新增内嵌4大函数式接口 可直接调用
1> Consumer :消费型接口 void accept(T t);
2> Supplier :供给型接口 T get();
3> Function<T,R> :函数型接口 R apply(T t);
4> Predicate :断言型接口 boolean test(T t);
实例一、
Consumer :消费型接口 void accept(T t); 有入参无返回参数
/**
- 消费形接口,有参数,无返回值
*/
public class ConsumerTest {
public static void main(String[] args) {
summer(10000, m -> System.out.println("世界那么大,我想去看看,可是钱包仅有:"+m+"元"));
}
public static void summer(double money, Consumer<Double> con) {
con.accept(money);
}
}
实例二、
2> Supplier :供给型接口 T get();
/**
- 供给形接口,无参数有返回值
*/
public class SupplierTest {
public static void main(String[] args) {
List<Double> list = getRandomValue(5, () -> Math.random() * 100);
for (Double d : list) {
System.out.println(d);
}
}
public static List<Double> getRandomValue(int num, java.util.function.Supplier<Double> sup) {
List<Double> list = new ArrayList<>();
for (int i = 0; i < num; i++) {
list.add(sup.get());
}
return list;
}
}
实例三、
Function<T,R> :函数型接口 R apply(T t);
/**
* 函数形接口,有参数,有
*/
public class ConsumerTest {
public static void main(String[] args) {
String str = strHandler("一花一世界,一叶一菩提!", s -> s.substring(2,5));
System.out.println(str);
}
public static String strHandler(String str, Function<String, String> fun) {
return fun.apply(str);
}
}
实例四、
Predicate :断言型接口 boolean test(T t);
/**
* 断言形接口,有参数,返回boolean
*/
public class PredicateTest {
public static void main(String[] args) {
List<String> list = Arrays.asList("北京","南京","东京","长安","洛阳");
list = filterStr(list, s->s.contains("京"));
list.forEach(System.out::println);
}
public static List<String> filterStr(List<String> list, Predicate<String> predicate) {
List<String> stringList = new ArrayList<>();
for (String str : list) {
if (predicate.test(str))
stringList.add(str);
}
return stringList;
}
}
六、自定义函数编程
一、步骤
1、定义函数接口 注 只能有一个等待被实现的方法其余可以是default修饰
@FunctionalInterface
public interface OpreFunction<R,T>{
R opreafn(R r,T t);
}
2、传递参数
public static Integer opfun(Integer a, Integer b, OpreFunction<Integer,Integer> opreFunction){
return opreFunction.opreafn(a,b);
}
3、实现功能
System.out.println(TestController.opfun(12,2,(x,y)->x+y));
使用自定义函数编程、可以实现类似策略模式的效果
四大核心函数:
1>、Consumer:消费型接口(void accept(T t))
/**
* 消费型接口Consumer<T>
*/
@Test
public void test1 () {
consumo(500, (x) -> System.out.println(x));
}
public void consumo (double money, Consumer<Double> c) {
c.accept(money);
}
以上为消费型接口,有参数,无返回值类型的接口。
2>、Supplier:供给型接口(T get())
/**
* 供给型接口,Supplier<T>
*/
@Test
public void test2 () {
Random ran = new Random();
List<Integer> list = supplier(10, () -> ran.nextInt(10));
for (Integer i : list) {
System.out.println(i);
}
}
/**
* 随机产生sum个数量得集合
* @param sum 集合内元素个数
* @param sup
* @return
*/
public List<Integer> supplier(int sum, Supplier<Integer> sup){
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < sum; i++) {
list.add(sup.get());
}
return list;
}
上面就是一个供给类型得接口,只有产出,没人输入,就是只有返回值,没有入参 ——工厂函数
3>、Function<T, R>:函数型接口(R apply(T t))
/**
* 函数型接口:Function<R, T>
*/
@Test
public void test3 () {
String s = strOperar(" asdf ", x -> x.substring(0, 2));
System.out.println(s);
String s1 = strOperar(" asdf ", x -> x.trim());
System.out.println(s1);
}
/**
* 字符串操作
* @param str 需要处理得字符串
* @param fun Function接口
* @return 处理之后得字符传
*/
public String strOperar(String str, Function<String, String> fun) {
return fun.apply(str);
}
上面就是一个函数型接口,输入一个类型得参数,输出一个类型得参数,当然两种类型可以一致。
***4>、Predicate:断言型接口(boolean test(T t))***
/**
* 断言型接口:Predicate<T>
*/
@Test
public void test4 () {
List<Integer> l = new ArrayList<>();
l.add(102);
l.add(172);
l.add(13);
l.add(82);
l.add(109);
List<Integer> list = filterInt(l, x -> (x > 100));
for (Integer integer : list) {
System.out.println(integer);
}
}
/**
* 过滤集合
* @param list
* @param pre
* @return
*/
public List<Integer> filterInt(List<Integer> list, Predicate<Integer> pre){
List<Integer> l = new ArrayList<>();
for (Integer integer : list) {
if (pre.test(integer))
l.add(integer);
}
return l;
}
上面就是一个断言型接口,输入一个参数,输出一个boolean类型得返回值。
5>、其他类型的一些函数式接口
1).BiFunction<T, U, R>
参数类型有2个,为T,U,返回值为R,其中方法为R apply(T t, U u)
2).UnaryOperator(Function子接口)
参数为T,对参数为T的对象进行一元操作,并返回T类型结果,其中方法为T apply(T t)
3).BinaryOperator(BiFunction子接口)
参数为T,对参数为T得对象进行二元操作,并返回T类型得结果,其中方法为T apply(T t1, T t2)
4).BiConsumcr(T, U)
参数为T,U无返回值,其中方法为 void accept(T t, U u)
5).ToIntFunction、ToLongFunction、ToDoubleFunction
参数类型为T,返回值分别为int,long,double,分别计算int,long,double得函数。
6).IntFunction、LongFunction、DoubleFunction
参数分别为int,long,double,返回值为R。
jdk 8新特性——下 链接地址:https://blog.csdn.net/weixin_42083036/article/details/102951697