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