jdk1.8新增特性

接口的默認(rèn)方法 default關(guān)鍵字

可以在接口中定義方法的默認(rèn)實(shí)現(xiàn)诸衔,并且實(shí)現(xiàn)類也可以選擇是否重新默認(rèn)實(shí)現(xiàn)。

lambda表達(dá)式

新增了@FunctionalInterface注解颇玷,該注解添加在只有一個(gè)抽象方法的接口上笨农,表示可以作為函數(shù)傳入。如果被添加該注解的接口有多個(gè)抽象方法帖渠,則會(huì)編譯不通過(guò)谒亦。

函數(shù)式編程

以前在使用像Comparator這種接口時(shí),一般是使用匿名內(nèi)部類來(lái)實(shí)現(xiàn)空郊,還有就是實(shí)現(xiàn)Runable接口等份招。

1.8之前:

 ArrayList<Student> students = new ArrayList<>(10);
        students.sort(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getName().compareTo(o2.getName());
            }
        });

lambda:

        ArrayList<Student> students = new ArrayList<>(10);
        students.sort((Student o1,Student o2) -> o1.getName().compareTo(o2.getName()));

lambda簡(jiǎn)化:省去參數(shù)類型等定義

 ArrayList<Student> students = new ArrayList<>(10);
        students.sort((o1,o2) -> o1.getName().compareTo(o2.getName()));

使用Comparator的靜態(tài)方法,傳入比較的key的方法函數(shù)

ArrayList<Student> students = new ArrayList<>(10);
        students.sort(Comparator.comparing(Student::getName));

引入lambda表達(dá)式后狞甚,可以使這種實(shí)現(xiàn)更為簡(jiǎn)單锁摔。

lambda表達(dá)式內(nèi)可以對(duì)靜態(tài)變量和對(duì)象變量進(jìn)行讀寫(xiě),對(duì)局部變量只能夠讀哼审,并且被表達(dá)式內(nèi)讀的局部變量在之后不能被改變(類似于final)谐腰。

雙冒號(hào)::的使用

可以使用雙冒號(hào)來(lái)訪問(wèn)類的構(gòu)造函數(shù),靜態(tài)函數(shù)和對(duì)象函數(shù).

  1. 構(gòu)造函數(shù):

定義Person類

public class Person {
Person(String nikename,String username){
        this.nikename=nikename;
        this.username=username;
    }
    private String nikename;
    private String username;
}

定義PersonFactory接口

@FunctionalInterface
public interface PersonFactory<P> {
    P creat(String nikename,String username);
}

訪問(wèn)構(gòu)造函數(shù)

 PersonFactory<Person> personFactory = Person::new;
 Person person = personFactory.creat("羊肉小籠包", "大哥你好");

在上面的代碼中涩盾,Person::new相當(dāng)于create(String,String)方法的實(shí)現(xiàn)十气,而這個(gè)實(shí)現(xiàn)就是Person類的構(gòu)造函數(shù),相當(dāng)于使用構(gòu)造函數(shù)實(shí)現(xiàn)接口的唯一抽象方法旁赊。

  1. 靜態(tài)方法

    Person類中有一個(gè)靜態(tài)方法run

    public class Person {
     public static String run(){
            return "Im running!";
        }
    }
    

    定義Action接口桦踊,內(nèi)有一個(gè)抽象方法doThing

    @FunctionalInterface
    public interface Action<T>{
        T doThing();
    }
    

    測(cè)試

    Action<String> run = Person::run;
            System.out.println(run.doThing());
    // 打印出"Im running!"
    
  2. 實(shí)例方法

    Person類中有一個(gè)實(shí)例方法eat

    public class Person {
    public String eat(String food){
            return food + " is delicious!";
        }
        }
    

    定義接口LifeAction

    @FunctionalInterface
    public interface LifeAction<T,P> {
        T requiredAction(P something);
    }
    

    測(cè)試

    Person person = new Person();
    LifeAction<String, String> eat = person::eat;
    System.out.println(eat.requiredAction("noodle"));
    // 打印noodle is delicious!
    

新增函數(shù)式接口

Predicate接口

   @FunctionalInterface
   public interface Predicate<T> {
       boolean test(T t);
       default Predicate<T> and(Predicate<? super T> other);
    default Predicate<T> negate();
       default Predicate<T> or(Predicate<? super T> other);
       static <T> Predicate<T> isEqual(Object targetRef);
   }

demo

     private static boolean check(Integer num){
           // 使用靜態(tài)方法根據(jù)一個(gè)參數(shù)初始化
           Predicate<Object> equal = Predicate.isEqual(num);
           // 使用一個(gè)lambda表達(dá)式初始化
           Predicate<Integer> checkNum = (i)->i>1;
           // 將兩種判斷取邏輯或(有短路)default方法
           Predicate<Integer> or = checkNum.or((i -> i < -1));
           // 將兩種判斷取邏輯與(有短路)default方法
           Predicate<Integer> and = or.and((i) -> i == 1);
           // 將判斷取反
           Predicate<Integer> negate = and.negate();
           return or.test(num);
       }

Function接口

   @FunctionalInterface
   public interface Function<T, R> {
       R apply(T t);
       default <V> Function<V, R> compose(Function<? super V, ? extends T> before);
       default <V> Function<T, V> andThen(Function<? super R, ? extends V> after);
       static <T> Function<T, T> identity();
   }

demo

           // 返回參數(shù)本身的function
           Function<Object, Object> identity = Function.identity();
           // 定義一個(gè)有邏輯的function
           Function<String, String> a = (s)->s+" 11111111";
           // 定義一個(gè)有后續(xù)邏輯的function,先執(zhí)行的function的返回值
        // 就是后執(zhí)行的function的參數(shù)终畅,類型需要匹配
           Function<String, String> function = a.andThen((s) -> s+" 33333333");
           // 定義一個(gè)有前置邏輯的function籍胯,前置執(zhí)行的function的
        // 返回值就是該function的參數(shù)
           Function<Object, String> compose = a.compose((s) -> s + " 222222");
   

Supplier接口

Supplier

   @FunctionalInterface
   public interface Supplier<T> {
       T get();
   }

demo

   public class SupplierDemo {
       public static void main(String[] args) {
           Supplier<SupplierDemo> supplier = SupplierDemo::new;
           SupplierDemo supplierDemo = supplier.get();
           Supplier<String> a = SupplierDemo::a;
           System.out.println(a.get());
           //打印aaaa
       }
       public static String a(){
           return "aaaa";
       }
   }

Suplier接口可以以任何無(wú)參數(shù)的類中方法作為實(shí)現(xiàn),

當(dāng)然無(wú)參數(shù)類中方法必須無(wú)重寫(xiě)方法离福。

Consumer接口

Consumer

這個(gè)接口就是封裝了一個(gè)消費(fèi)的操作杖狼,然后有一個(gè)對(duì)傳入數(shù)據(jù)的二次消費(fèi)的默認(rèn)實(shí)現(xiàn)

   @FunctionalInterface
   public interface Consumer<T> {
       void accept(T t);
       default Consumer<T> andThen(Consumer<? super T> after) {
           Objects.requireNonNull(after);
           return (T t) -> { accept(t); after.accept(t); };
       }
   }

demo:

   public class ConsumerDemo {
       public static void main(String[] args) {
           Consumer<String> first = (o)-> System.out.println(o+"1");
           Consumer<String> second = first.andThen((o) -> System.out.println(o + ".....2"));
           second.accept("parameter");
       }
   }
   //打印
   //parameter1
   //parameter.....2

Comparator接口

該接口是1.2版本中添加的接口,這次1.8版本將這個(gè)接口添加了@FunctionInterface注解妖爷,并且添加了多個(gè)靜態(tài)方法和默認(rèn)實(shí)現(xiàn)蝶涩。

具體請(qǐng)看另一篇文章:

Comparetor接口和Comparable接口的區(qū)別

集合的Stream操作

串行stream:Collection.stream

并行stream:Collection.parallelStream

使用集合的Stream操作是不影響原Collection的值的理朋。

過(guò)濾元素

其中Filter方法的參數(shù)是Predicate接口,也就是判斷邏輯

list.stream().filter(s -> s.startsWith("b")).forEach(System.out::println);

集合排序

sorted方法無(wú)參時(shí)是使用自然排序绿聘,如果有參嗽上,參數(shù)為Comparator接口

list.parallelStream().sorted().forEach(System.out::println);
list.parallelStream().sorted(String::compareTo).forEach(System.out::println);

集合迭代

forEach方法參數(shù)為Consumer接口

list.forEach(System.out::println);
list.stream().forEach(System.out::println);
list.parallelStream().forEach(System.out::println);

集合元素處理

map方法參數(shù)為Function接口,需要實(shí)現(xiàn)對(duì)集合元素處理邏輯熄攘,返回新的Stream

list.stream().map((String o)->Integer.valueOf(o.substring(3))).forEach(System.out::println);

結(jié)合元素匹配

類似于contain方法兽愤,Stream的match方法可以根據(jù)實(shí)現(xiàn)的匹配邏輯判斷集合中是否含有該種元素。方法參數(shù)是Predicate接口,返回值是boolean挪圾。

全部匹配
list.stream().allMatch(o -> o.startsWith("a"))
是否存在匹配
list.stream().anyMatch(o->o.startsWith("a"));
無(wú)匹配
list.stream().noneMatch(o->o.startsWith("a"));

集合元素計(jì)數(shù)

list.stream.filter(s->s.startsWith("a").count())

集合計(jì)算

System.out.println(list.stream().reduce("head:", (o1, o2) -> o1 + o2));
// 打印出head:元素拼接
// 其中第一個(gè)參數(shù)是作為初始變量浅萧,作為o1傳入了方法內(nèi)

Optional類

一個(gè)封裝泛型數(shù)據(jù)的容器,可以很方便的用來(lái)判斷數(shù)據(jù)是否為null哲思,可以作為方法的返回類型和方法入?yún)ⅰ?/p>

demo

 public static Optional<User> getInstace(User str){
        // 這種實(shí)例化方式參數(shù)可以為null
        Optional<User> strOption = Optional.ofNullable(str);
        // 這種實(shí)例化方式參數(shù)不能為null洼畅,否則會(huì)報(bào)空指針異常
        Optional<User> str1 = Optional.of(str);
        return strOption;
    }

    public static User orElse(User user){
        // 可以在獲得元素的時(shí)候有一個(gè)默認(rèn)
        Optional<User> user1 = Optional.ofNullable(user);
        User et = user1.orElse(new User("3", "ET"));
        return et;
    }
    public static User orElseGet(User user){
        // 在獲取元素時(shí)如果為null,調(diào)用一個(gè)Supplier的實(shí)現(xiàn)構(gòu)造一個(gè)新的元素
        Optional<User> user1 = Optional.ofNullable(user);
        return user1.orElseGet(() -> new User("3", "ET"));
    }

    public static Optional<User> filter(User user){
        // 過(guò)濾容器內(nèi)元素棚赔,使用predicate接口帝簇,如果test方法為false則返回一個(gè)空的容器
        Optional<User> user1 = Optional.ofNullable(user);
        return user1.filter((o) -> o.getSex() == null);
    }

新的時(shí)間日期API:

LocalDate

獲取當(dāng)前的date
        // 獲取指定zone現(xiàn)在的date
        String s = LocalDate.now(ZoneId.of("America/Chicago")).toString();
        // 獲取當(dāng)前地區(qū)現(xiàn)在的date
        String s1 = LocalDate.now().toString();
        // 獲取當(dāng)前zone現(xiàn)在的date
        LocalDate.now(Clock.systemDefaultZone()).toString();

根據(jù)指定年月日獲取localDate
        // 根據(jù)指定的年月日生成localDate
        LocalDate of = LocalDate.of(year, month, day);
        // 這里是把月份int用枚舉值代替
        LocalDate of1 = LocalDate.of(year, Month.APRIL, day);
        // 1970-01-01加上Long類型參數(shù)天的日期
        String s = LocalDate.ofEpochDay(356 * 10L).toString();

獲取當(dāng)月的特殊日期

        // 獲取本月的第一天日期
        LocalDate firstDay = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
        // 獲取本月的最后一天
        LocalDate lastDay = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
        // 今天是本月幾日
        int dayOfMonth = LocalDate.now().getDayOfMonth();
        // 今天是周幾
        int value = LocalDate.now().getDayOfWeek().getValue();
        // 獲取當(dāng)前年份
        int year1 = LocalDate.now().getYear();
        // 獲取當(dāng)前月份
        int month1 = LocalDate.now().getMonth().getValue();

LocalTime

與LocalDate類似

獲取LocalTime實(shí)例
        // 該實(shí)例會(huì)生成帶有毫秒數(shù)的一個(gè)LocalTime
        LocalTime now = LocalTime.now();
        // 其參數(shù)為,時(shí)忆嗜、分己儒、秒、納秒
        LocalTime of = LocalTime.of(1, 2, 2, 3);
        LocalTime of1 = LocalTime.of(1, 2, 3);
操作LocalTime實(shí)例
        LocalTime now = LocalTime.now();
        LocalTime localTime = now.plusHours(1);
        LocalTime localTime1 = now.withMinute(12);
        LocalTime localTime2 = localTime1.withHour(1);

LocalDateTime

該類包含了LocalDate和LocalTime的一些方法捆毫,如getMonth闪湾,getHour等。

LocalDate绩卤、LocalTime和LocalDateTime之間的轉(zhuǎn)化

        LocalDateTime of1 = LocalDateTime.of(LocalDate.now(), LocalTime.now());
        LocalDate localDate = of1.toLocalDate();
        LocalTime localTime = of1.toLocalTime();

DateTimeFormatter

格式化LocalDate途样、LocalTime和LocalDateTime三個(gè)類,使用方式相同

轉(zhuǎn)為格式String
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime now = LocalDateTime.now();
        String format = now.format(dateTimeFormatter);

String轉(zhuǎn)日期時(shí)間類
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String dateTimeStr = "1992-11-02 11:32:23";
        TemporalAccessor parse = dateTimeFormatter.parse(dateTimeStr);
        LocalDateTime from = LocalDateTime.from(parse);

Clock

Clock是一個(gè)抽象類濒憋,在其內(nèi)部有四個(gè)內(nèi)部類:

  1. SystemClock
  2. FixedClock
  3. OffsetClock
  4. TickClock

支持多重注解

原來(lái)需要使用數(shù)據(jù)類型存儲(chǔ)多個(gè)相同的注解何暇,現(xiàn)在可以將多個(gè)形同注解加載同一處,給注解添加@Repatable元注解即可凛驮,

編譯器會(huì)自動(dòng)幫你將相同注解存儲(chǔ)在注解的數(shù)組屬性里面裆站。

StampedLock升級(jí)的讀寫(xiě)鎖

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市黔夭,隨后出現(xiàn)的幾起案子宏胯,更是在濱河造成了極大的恐慌,老刑警劉巖本姥,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肩袍,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡婚惫,警方通過(guò)查閱死者的電腦和手機(jī)氛赐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門魂爪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人艰管,你說(shuō)我怎么就攤上這事滓侍。” “怎么了牲芋?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵粗井,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我街图,道長(zhǎng),這世上最難降的妖魔是什么懒构? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任餐济,我火速辦了婚禮,結(jié)果婚禮上胆剧,老公的妹妹穿的比我還像新娘絮姆。我一直安慰自己,他們只是感情好秩霍,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布篙悯。 她就那樣靜靜地躺著,像睡著了一般铃绒。 火紅的嫁衣襯著肌膚如雪鸽照。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 50,084評(píng)論 1 291
  • 那天颠悬,我揣著相機(jī)與錄音矮燎,去河邊找鬼。 笑死赔癌,一個(gè)胖子當(dāng)著我的面吹牛诞外,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播灾票,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼峡谊,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了刊苍?” 一聲冷哼從身側(cè)響起既们,我...
    開(kāi)封第一講書(shū)人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎班缰,沒(méi)想到半個(gè)月后贤壁,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡埠忘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年脾拆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了馒索。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡名船,死狀恐怖绰上,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情渠驼,我是刑警寧澤蜈块,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布,位于F島的核電站迷扇,受9級(jí)特大地震影響百揭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蜓席,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一器一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧厨内,春花似錦祈秕、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至瞭亮,卻和暖如春方仿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背统翩。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工兼丰, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人唆缴。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓鳍征,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親面徽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子艳丛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351