真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

JDK新特性-創(chuàng)新互聯(lián)

JDK1.5新特性

JDK1.5的新特性:

自動(dòng)拆裝箱 , 泛型 , 增強(qiáng)for , 靜態(tài)導(dǎo)入 , 可變參數(shù) , 枚舉

枚舉概述: 就是一個(gè)類只能存在幾個(gè)固定的對(duì)象,那么這個(gè)就是枚舉.我們就可以使用這些對(duì)象可以表示一些固定的值.
舉例:一周只有7天,一年只有12個(gè)月等。

成都創(chuàng)新互聯(lián)公司是專業(yè)的冀州網(wǎng)站建設(shè)公司,冀州接單;提供網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì),網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行冀州網(wǎng)站開發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!
枚舉

定義枚舉類要用關(guān)鍵字enum
所有枚舉類都是Enum的子類
枚舉類的第一行上必須是枚舉項(xiàng),最后一個(gè)枚舉項(xiàng)后的分號(hào)是可以省略的,但是如果枚舉類有其他的東西,這個(gè)分號(hào)就不能省略。建議不要省略
枚舉類可以有構(gòu)造器,但必須是private的,它默認(rèn)的也是private的。枚舉項(xiàng)的用法比較特殊:枚舉(“”);
枚舉類也可以有抽象方法,但是枚舉項(xiàng)必須重寫該方法
枚舉在switch語(yǔ)句中的使用

枚舉類的常見方法

int ordinal() 返回枚舉項(xiàng)的序號(hào)
int compareTo(E o) 比較兩個(gè)枚舉項(xiàng)的 返回的是兩個(gè)枚舉項(xiàng)序號(hào)的 差值
String name() 獲取枚舉項(xiàng)的名稱
String toString()獲取枚舉項(xiàng)的名稱
T valueOf(Class type,String name) 用來(lái)獲取指定的枚舉項(xiàng) 參數(shù)1:枚舉類對(duì)應(yīng)的字節(jié)碼對(duì)象 參數(shù)2 枚舉項(xiàng)的名稱
values() 獲取所有的枚舉項(xiàng)
此方法雖然在JDK文檔中查找不到,但每個(gè)枚舉類都具有該方法,它遍歷枚舉類的所有枚舉值非常方便

列(枚舉):
  • 1:
    public static void main(String[] args) {

    // 測(cè)試
    Direction front = Direction.FRONT ;
    Direction behind = Direction.BEHIND;
    Direction left = Direction.LEFT ;
    Direction right = Direction.RIGHT ;

    System.out.println(front.ordinal());
    System.out.println(behind.ordinal());
    System.out.println(left.ordinal());
    System.out.println(right.ordinal());

    System.out.println("----------------------------------");

    System.out.println(front.compareTo(right));

    System.out.println("----------------------------------");

    System.out.println(front.name());

    System.out.println("----------------------------------");

    System.out.println(front.toString());
    System.out.println(front);

    System.out.println("----------------------------------");

    // T valueOf(Class type,String name): 用來(lái)獲取指定的枚舉項(xiàng)
    // type: 表示的是對(duì)應(yīng)的枚舉的字節(jié)碼文件對(duì)象
    // name: 就是枚舉項(xiàng)的名稱
    Direction direction = Direction.valueOf(Direction.class, "RIGHT") ;
    System.out.println(direction);

    System.out.println("----------------------------------");

    Direction[] directions = Direction.values() ;

    for(Direction d : directions){
    System.out.println(d);
    }

}

  • 2
    public enum Direction {
    FRONT("前"), AFTER("后"), LEFT("后"),RIGHT("右"); //下面如果有代碼,; 分號(hào)不要省略,每個(gè)枚舉項(xiàng),用逗號(hào)隔開
    private Direction(String name){}
    }

//public class Direction {
// //表示前后左右四個(gè)固定的值
// //ctrl+shift+U 轉(zhuǎn)換大小寫
// public static final org.westos.demo8.Direction FRONT = new org.westos.demo8.Direction("前");
// public static final org.westos.demo8.Direction AFTER = new org.westos.demo8.Direction("后");
// public static final org.westos.demo8.Direction LEFT = new org.westos.demo8.Direction("左");
// public static final org.westos.demo8.Direction RIGHT = new org.westos.demo8.Direction("右");
// public String name;
//
// private Direction(String name) {
// this.name = name;
// }
//}
public class MyTest {
public static void main(String[] args) {
Direction front = Direction.FRONT;
Direction after = Direction.AFTER;
Direction left = Direction.LEFT;
Direction right = Direction.RIGHT;
System.out.println(front.toString());
System.out.println(after);
System.out.println(left);
System.out.println(right);

long num = 10_000_000_000L; //_充當(dāng)千位分割符

   //JUI JavaEE  B/S
   //C/S

}

}

JDK1.7新特性

二進(jìn)制字面量
JDK7開始,終于可以用二進(jìn)制來(lái)表示整數(shù)(byte,short,int和long)。
使用二進(jìn)制字面量的好處是,可以使代碼更容易被理解。語(yǔ)法非常簡(jiǎn)單,只要在二進(jìn)制數(shù)值前面加 0b或者0B
int x = 0b110110
數(shù)字字面量可以出現(xiàn)下劃線

為了增強(qiáng)對(duì)數(shù)值的閱讀性,如我們經(jīng)常把數(shù)據(jù)用逗號(hào)分隔一樣。JDK7提供了_對(duì)數(shù)據(jù)分隔。
舉例:
int x = 100_1000;
注意事項(xiàng):
不能出現(xiàn)在進(jìn)制標(biāo)識(shí)和數(shù)值之間
不能出現(xiàn)在數(shù)值開頭和結(jié)尾
不能出現(xiàn)在小數(shù)點(diǎn)旁邊

switch 語(yǔ)句可以用字符串
泛型可以簡(jiǎn)化
異常的多個(gè)catch可以合并

JDK1.8新特性

新增的日期時(shí)間API
LocalDate、 LocalTime、 LocalDateTime類

LocalDate、 LocalTime、 LocalDateTime類的實(shí)例是不可變的對(duì)象,分別表示使用 ISO-8601日歷系統(tǒng)的日期、時(shí)間、日期和時(shí)間它們提供了簡(jiǎn)單的日期或時(shí)間,并不包含當(dāng)前的時(shí)間信息。也不包含與時(shí)區(qū)相關(guān)的信息。
注: ISO-8601日歷系統(tǒng)是國(guó)際標(biāo)準(zhǔn)化組織制定的現(xiàn)代公民的日期和時(shí)間的表示法
這些新增的日期時(shí)間API都在 java.time包下

獲取對(duì)象的方法

1通過(guò)靜態(tài)方法 now();
例如:LocalDateTime ldt = LocalDateTime.now();

方式2通過(guò)靜態(tài)方法of()方法參數(shù)可以指定年月日時(shí)分秒
    例如:LocalDateTime of = LocalDateTime.of(2018, 12, 30, 20, 20, 20);
常用方法
1.與獲取相關(guān)的方法:get系類的方法
    ldt.getYear();獲取年
    ldt.getMinute();獲取分鐘
    ldt.getHour();獲取小時(shí)
    getDayOfMonth 獲得月份天數(shù)(1-31)
    getDayOfYear 獲得年份天數(shù)(1-366)
    getDayOfWeek 獲得星期幾(返回一個(gè) DayOfWeek枚舉值)
    getMonth 獲得月份, 返回一個(gè) Month 枚舉值
    getMonthValue 獲得月份(1-12)
    getYear 獲得年份
2.格式化日期日期字符串的方法 format()
    例如:String yyyy = ldt.format(DateTimeFormatter.ofPattern("yyyy"));
3.轉(zhuǎn)換的方法 toLocalDate();toLocalTime();
    例如:LocalDate localDate = ldt.toLocalDate();
    例如:LocalTime localTime = ldt.toLocalTime();
4.判斷的方法
    isAfter()判斷一個(gè)日期是否在指定日期之后
    isBefore()判斷一個(gè)日期是否在指定日期之前
    isLeapYear()判斷是否是閏年注意是LocalDate類中的方法
        例如:  boolean after = ldt.isAfter(LocalDateTime.of(2024, 1, 1, 2, 3));
        例如  boolean b= LocalDate.now().isLeapYear();

5.解析的靜態(tài)方法parse("2007-12-03T10:15:30");
    paser() 將一個(gè)日期字符串解析成日期對(duì)象,注意字符串日期的寫法的格式要正確,否則解析失敗
        例如:LocalDateTime parse = LocalDateTime.parse("2007-12-03T10:15:30");

    按照我們指定的格式去解析:

    注意細(xì)節(jié):如果用LocalDateTime 想按照我們的自定義的格式去解析,注意
    日期字符串的 年月日時(shí)分秒要寫全,不然就報(bào)錯(cuò)
        LocalDateTime ldt4 = LocalDateTime.now();
        DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime.parse("2018-01-21 20:30:36", formatter2);

6.添加年月日時(shí)分秒的方法 plus系列的方法 都會(huì)返回一個(gè)新的LocalDateTime的對(duì)象
    LocalDateTime localDateTime = ldt.plusYears(1);
    LocalDateTime localDateTime1 = ldt.plusMonths(3);
    LocalDateTime localDateTime2=ldt.plusHours(10);
7.減去年月日時(shí)分秒的方法 minus 系列的方法 注意都會(huì)返回一個(gè)新的LocalDateTime的對(duì)象
    例如:LocalDateTime localDateTime2 = ldt.minusYears(8);
8.指定年月日時(shí)分秒的方法 with系列的方法 注意都會(huì)返回一個(gè)新的LocalDateTime的對(duì)象
    例如 LocalDateTime localDateTime3 = ldt.withYear(1998);
      //獲取這個(gè)月的第幾個(gè)星期幾是幾號(hào),比如 TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.FRIDAY) 代表的意思是這個(gè)月的第二個(gè)星期五是幾號(hào)
          // TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.FRIDAY)
          LocalDateTime with2 = now.with(TemporalAdjusters.dayOfWeekInMonth(2,DayOfWeek.FRIDAY));

Instant時(shí)間戳類從1970-01-01 00:00:00 截止到當(dāng)前時(shí)間的毫秒值

1獲取對(duì)象的方法 now()
注意默認(rèn)獲取出來(lái)的是當(dāng)前的美國(guó)時(shí)間和我們相差八個(gè)小時(shí)
Instant ins = Instant.now();
System.out.println(ins);
我們?cè)跂|八區(qū) 所以可以加8個(gè)小時(shí) 就是我們的北京時(shí)間

  1. Instant中設(shè)置偏移量的方法:atOffset() 設(shè)置偏移量
    OffsetDateTime time = ins.atOffset(ZoneOffset.ofHours(8));
    System.out.println(time);
    3.獲取系統(tǒng)默認(rèn)時(shí)區(qū)時(shí)間的方法atZone()
    方法的參數(shù)是要一個(gè)時(shí)區(qū)的編號(hào)可以通過(guò)時(shí)區(qū)編號(hào)類獲取出來(lái)
    ZoneId.systemDefault()獲取本地的默認(rèn)時(shí)區(qū)ID
    ZonedDateTime zonedDateTime = ins.atZone(ZoneId.systemDefault());
    System.out.println(zonedDateTime);
    4.get系列的方法

    getEpochSecond() 獲取從1970-01-01 00:00:00到當(dāng)前時(shí)間的秒值
    getNano()方法是把獲取到的當(dāng)前時(shí)間的秒數(shù) 換算成納秒
    long epochSecond = ins.getEpochSecond();//獲取從1970-01-01 00:00:00到當(dāng)前時(shí)間的秒值
    getNano()方法是把獲取到的當(dāng)前時(shí)間的豪秒數(shù) 換算成納秒 比如當(dāng)前時(shí)間是2018-01-01 14:00:20:30
    那就把30豪秒換算成納秒 int nano = ins.getNano();

  2. ofEpochSecond()方法 給計(jì)算機(jī)元年增加秒數(shù)
    例如 Instant instant = Instant.ofEpochSecond(5);
    System.out.println(instant);
    單位換算
    0.1 毫秒 = 10 的5次方納秒 = 100000 納秒
    1 毫秒 = 1000 微妙 = 1000000 納秒

    Duration : 用于計(jì)算兩個(gè)“時(shí)間”間隔的類

    Period : 用于計(jì)算兩個(gè)“日期”間隔的類

    列如:

    Duration類中靜態(tài)方法between()
    Instant start = Instant.now();
    for(int i=0;i<1000L;i++){
    System.out.println("循環(huán)內(nèi)容");
    }
    Instant end = Instant.now();
    靜態(tài)方法:between() 計(jì)算兩個(gè)時(shí)間的間隔,默認(rèn)是秒
    Duration between = Durati’on.between(start, end);
    Duration中的toMillis()方法:將秒轉(zhuǎn)成毫秒
    System.out.println(between.toMillis());

Period類 中的靜態(tài)方法between()
計(jì)算兩個(gè)日期之間的間隔
LocalDate s = LocalDate.of(1985, 03, 05);
LocalDate now = LocalDate.now();
Period be = Period.between(s, now);
System.out.println(be.getYears());間隔了多少年
System.out.println(be.getMonths());間隔了多少月
System.out.println(be.getDays());間隔多少天

TemporalAdjuster : 時(shí)間校正器,是個(gè)接口,

一般我們用該接口的一個(gè)對(duì)應(yīng)的工具類 TemporalAdjusters中的一些常量,來(lái)指定日期

例如:

LocalDate now = LocalDate.now();
System.out.println(now);
1 使用TemporalAdjusters自帶的常量來(lái)設(shè)置日期
LocalDate with = now.with(TemporalAdjusters.lastDayOfYear());
System.out.println(with);
2 采用TemporalAdjusters中的next方法來(lái)指定日期
LocalDate date = now.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
System.out.println(date);
例如:TemporalAdjusters.next(DayOfWeek.SUNDAY) 本周的星期天
例如:TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY) 下一周的星期一
3 采用自定義的方式來(lái)指定日期 比如指定下個(gè)工作日
LocalDateTime ldt = LocalDateTime.now();
LocalDateTime workDay = ldt.with(new TemporalAdjuster() {@Override
br/>@Override
//向下轉(zhuǎn)型
LocalDateTime ld = (LocalDateTime) temporal;
//獲取這周的星期幾
DayOfWeek dayOfWeek = ld.getDayOfWeek();
if (dayOfWeek.equals(DayOfWeek.FRIDAY)) {
return ld.plusDays(3);//如果這天是星期五,那下個(gè)工做日就加3天
} else if (dayOfWeek.equals(DayOfWeek.SATURDAY)) {
return ld.plusDays(2);//如果這天是星期六,那下個(gè)工做日就加2天
} else {
//其他就加一天
return ld.plusDays(1);
}
}
});

System.out.println(workDay);

DateTimeFormatter :解析和格式化日期或時(shí)間的類

1.獲取對(duì)象的方式,通過(guò)靜態(tài)方法ofPattern("yyyy-MM-dd");
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDateTime now = LocalDateTime.now();
2.format()方法把一個(gè)日期對(duì)象的默認(rèn)格式 格式化成指定的格式
String format1 = dateFormat.format(now);
System.out.println(format1);
3.格式化日期 方式2使用日期類中的format方法 傳入一個(gè)日期格式化類對(duì)象

LocalDateTime now1 = LocalDateTime.now();
使用日期類中的format方法 傳入一個(gè)日期格式化類對(duì)象
使用DateTimeFormatter中提供好的日期格式常量
now1.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);

4.使用自定義的日期格式格式化字符串
DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");//自定義一個(gè)日期格式
String time = now1.format(timeFormat);
System.out.println(time);

  1. 把一個(gè)日期字符串轉(zhuǎn)成日期對(duì)象
    使用日期類中的parse方法傳入一個(gè)日期字符串,傳入對(duì)應(yīng)的日期格式化類
    DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    LocalDateTime parse = LocalDateTime.parse(time, timeFormat);
    System.out.println(parse);

    ZonedDate,ZonedTime、ZonedDateTime : 帶時(shí)區(qū)的時(shí)間或日期

    用法和 LocalDate、 LocalTime、 LocalDateTime 一樣 只不過(guò)ZonedDate,ZonedTime、ZonedDateTime 這三個(gè)帶有當(dāng)前系統(tǒng)的默認(rèn)時(shí)區(qū)

    ZoneID 世界時(shí)區(qū)類

    1.獲取世界各個(gè)地方的時(shí)區(qū)的集合 的方法getAvailableZoneIds()
    使用ZoneID中的靜態(tài)方法getAvailableZoneIds();來(lái)獲取
    例如:Set availableZoneIds = ZoneId.getAvailableZoneIds();
    2.獲取系統(tǒng)默認(rèn)時(shí)區(qū)的ID
    ZoneId zoneId = ZoneId.systemDefault(); //Asia/Shanghai
    3.獲取帶有時(shí)區(qū)的日期時(shí)間對(duì)象
    //創(chuàng)建日期對(duì)象
    LocalDateTime now = LocalDateTime.now();
    //獲取不同國(guó)家的日期時(shí)間根據(jù)各個(gè)地區(qū)的時(shí)區(qū)ID名創(chuàng)建對(duì)象
    ZoneId timeID = ZoneId.of("Asia/Shanghai");
    //根據(jù)時(shí)區(qū)ID獲取帶有時(shí)區(qū)的日期時(shí)間對(duì)象
    ZonedDateTime time = now.atZone(timeID);
    System.out.println(time);
    //方式2 通過(guò)時(shí)區(qū)ID 獲取日期對(duì)象
    LocalDateTime now2 = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
    System.out.println(now2);

    Lambda表達(dá)式

    Lambda 是一個(gè)匿名函數(shù),我們可以把 Lambda表達(dá)式理解為是一段可以傳遞的代碼(將代碼像數(shù)據(jù)一樣進(jìn)行傳遞)??梢詫懗龈?jiǎn)潔、更靈活的代碼。作為一種更緊湊的代碼風(fēng)格,使Java的語(yǔ)言表達(dá)能力得到了提升。
    public interface MyInterface {
    void show(int a,int b);
    }
    public class MyTest {
    public static void main(String[] args) {
    //JDK1.8之后提供了一種新的語(yǔ)法 叫做 Lambda表達(dá)式,可以簡(jiǎn)化我們對(duì)匿名內(nèi)部類的寫法,也可以作為參數(shù)傳遞
    //可以使用匿名內(nèi)部類來(lái)創(chuàng)建該接口的一個(gè)子類對(duì)象
    MyInterface myInterface = new MyInterface() {@Override
    br/>@Override
    System.out.println(a + b);
    }
    };
    myInterface.show(10, 20);
    //上面匿名內(nèi)部類的寫法,我可以用Lambda表達(dá)式來(lái)簡(jiǎn)化
    //Lambda 引入了一個(gè)箭頭 -> 符號(hào),將我們的表達(dá)式分為左右兩部分
    //箭頭左邊,就是接口中抽象方法的參數(shù)列表,箭頭右邊,是你對(duì)接口中的抽象方法的具體的重寫邏輯
    //參數(shù)列表中的數(shù)據(jù)類型 可以省略不寫
    MyInterface myInterface3 = (x, y) -> System.out.println(x + y);
    //當(dāng)然你可以寫上參數(shù)的,數(shù)據(jù)類型
    MyInterface myInterface2 = (int x, int y) -> System.out.println(x + y);

    //箭頭右邊對(duì)接口中方法的具體實(shí)現(xiàn)邏輯,如果只有一行代碼,那么{}也可以省略不寫,當(dāng)然也可以寫上
    MyInterface myInterface4 = (int x, int y) -> {
        System.out.println(x + y);
    };
    
    //如果你對(duì)接口中的抽象方法的實(shí)現(xiàn)邏輯有多條語(yǔ)句,那么這個(gè){} 必須寫上
    MyInterface myInterface5 = (int x, int y) -> {
        System.out.println(x + y);
        System.out.println(x-y);
        System.out.println(x*y);
    };
    myInterface2.show(10, 2000);

    }
    }
    public class MyTest2 {
    public static void main(String[] args) {
    MyInterface2 myInterface2 = new MyInterface2() {@Override
    br/>@Override
    return a + b;
    }
    };

    System.out.println("---------------------");
    //如果你對(duì)接口中的抽象方法具體的實(shí)現(xiàn)邏輯是一行語(yǔ)句,并且還有返回值,那么{}就省略不寫
    MyInterface2 myInterface3 = (x, y) -> x + y;
    //如果說(shuō)你要將return關(guān)鍵字寫上,那么你也要將{}寫上
    MyInterface2 myInterface4 = (x, y) -> {
        return x + y;
    };
    
    myTest(new MyInterface() {
        @Override
        public void show(int a, int b) {
            System.out.println(a+b);
        }
    });
    MyInterface myInterface=(x, y) -> System.out.println(x + y);
    myTest(myInterface);

    }

    private static void myTest(MyInterface myInterface) {
    myInterface.show(10,20);
    }
    }
    通過(guò)上面的對(duì)比,發(fā)現(xiàn)Lambda表達(dá)式式書寫起來(lái)更為簡(jiǎn)潔
    那我們具體來(lái)看一下Lambda表達(dá)式的書寫語(yǔ)法
    Lambda 表達(dá)式在Java 語(yǔ)言中引入了一個(gè)新的語(yǔ)法元素和操作符。這個(gè)操作符為 “ ->” , 該操作符被稱為 Lambda 操作符或箭頭操作符。它將 Lambda 分為兩個(gè)部分:
    左側(cè): 指定了 Lambda 表達(dá)式需要的所有參數(shù)
    右側(cè): 指定了 Lambda 體,即 Lambda 表達(dá)式要執(zhí)行的功能。
    public interface MyInteface3 {
    void test();
    void show();
    }
    public class MyTest2 {
    public static void main(String[] args) {
    new MyInteface3(){@Override
    br/>@Override

    }
    
        @Override
        public void show() {
    
        }
    };

    //Lambda 需要 函數(shù)式接口的支持
    // 函數(shù)式接口:這個(gè)接口中,僅僅只有 一個(gè)抽象方法
    // 函數(shù)式接口可以使用注解 @FunctionalInterface 來(lái)檢測(cè)這個(gè)接口是不是函數(shù)式接口
    //

    }
    }
    public class MyTest3 {
    public static void main(String[] args) {

    Integer[] integers=new Integer[]{10,30,40,1,3,5};
    Arrays.sort(integers, (a, b) -> b-a);
    
    System.out.println(Arrays.toString(integers));

    }
    }
    上述 Lambda 表達(dá)式中的參數(shù)類型都是由編譯器推斷得出的。 Lambda 表達(dá)式中無(wú)需指定類型,程序依然可以編譯,這是因?yàn)?javac 根據(jù)程序的上下文,在后臺(tái)推斷出了參數(shù)的類型。 Lambda 表達(dá)式的類型依賴于上下文環(huán)境,是由編譯器推斷出來(lái)的。這就是所謂的“類型推斷”.

    函數(shù)式接口

    Lambda表達(dá)式就是對(duì)函數(shù)式接口的一種簡(jiǎn)寫方式,所以只有是函數(shù)式接口,我們才能用Lambda表達(dá)式.再換句話說(shuō),Lambda表達(dá)式需要函數(shù)式接口的支持,那函數(shù)式接口我們可以自己定義,當(dāng)然JDK1.8也給我們提供了一些現(xiàn)成的函數(shù)式接口.

    函數(shù)式接口的定義是: 只包含一個(gè)抽象方法的接口,稱為函數(shù)式接口。

    你可以通過(guò) Lambda 表達(dá)式來(lái)創(chuàng)建該接口的對(duì)象
    我們可以在任意函數(shù)式接口上使用 @FunctionalInterface 注解,這樣做可以檢查它是否是一個(gè)函數(shù)式接口,同時(shí) javadoc 也會(huì)包含一條聲明,說(shuō)明這個(gè)接口是一個(gè)函數(shù)式接口.

    Java中提供的4大核心函數(shù)式接口

    函數(shù)式接口 參數(shù)類型 返回類型 用途
    Consumer
    消費(fèi)型接口 T void 對(duì)類型為T的對(duì)象應(yīng)用操
    作,包含方法:
    void accept(T t)
    Supplier
    供給型接口 無(wú) T 返回類型為T的對(duì)象,包
    含方法: T get();
    Function
    函數(shù)型接口
    T R 對(duì)類型為T的對(duì)象應(yīng)用操
    作,并返回結(jié)果。結(jié)果
    是R類型的對(duì)象。包含方
    法: R apply(T t);
    Predicate 斷言型接口
    T boolean 確定類型為T的對(duì)象是否
    滿足某約束,并返回
    boolean 值。包含方法
    boolean test(T t);

    其他函數(shù)式接口

    函數(shù)式接口 參數(shù)類型 返回類型 用途
    BiFunction
    T U R 對(duì)類型為 T, U 參數(shù)應(yīng)用
    操作, 返回 R 類型的結(jié)
    果。 包含方法為
    R apply(T t, U u);
    UnaryOperator
    (Function的子接口)
    T T 對(duì)類型為T的對(duì)象進(jìn)行一
    元運(yùn)算, 并返回T類型的
    結(jié)果。 包含方法為
    T apply(T t);
    BinaryOperator
    (BiFunction的子接口) T T T 對(duì)類型為T的對(duì)象進(jìn)行二
    元運(yùn)算, 并返回T類型的
    結(jié)果。 包含方法為
    T apply(T t1, T t2);
    BiConsumer
    T U void 對(duì)類型為T, U 參數(shù)應(yīng)用
    操作。 包含方法為
    void accept(T t, U u)
    ToIntFunction
    ToLongFunction
    ToDoubleFunction
    T int
    long
    double 分 別 計(jì) 算 int 、 long 、
    double、 值的函數(shù)
    IntFunction
    LongFunction
    DoubleFunction
    int
    long
    double R 參數(shù)分別為int、 long、
    double 類型的函數(shù)

    Stream API

    Stream 是 Java8 中處理集合的關(guān)鍵抽象概念,
    它可以指定你希望對(duì)集合進(jìn)行的操作,
    可以執(zhí)行非常復(fù)雜的查找、過(guò)濾和映射數(shù)據(jù)等操作。
    使用Stream API 對(duì)集合數(shù)據(jù)進(jìn)行操作,就類似于使用 SQL 執(zhí)行的數(shù)據(jù)庫(kù)查詢。也可以使用 Stream API 來(lái)并行執(zhí)行操作。
    簡(jiǎn)而言之,Stream API 提供了一種高效且易于使用的處理數(shù)據(jù)的方式。

    流到底是什么呢?

    是數(shù)據(jù)渠道,用于操作數(shù)據(jù)源(集合、數(shù)組等)所生成的元素序列。
    集合講的是數(shù)據(jù),流講的是計(jì)算!

    • 注意:
      ①Stream 自己不會(huì)存儲(chǔ)元素。
      ②Stream 不會(huì)改變?cè)磳?duì)象。相反,他們會(huì)返回一個(gè)持有結(jié)果的新Stream。
      ③Stream 操作是延遲執(zhí)行的。這意味著他們會(huì)等到需要結(jié)果的時(shí)候才執(zhí)行。

      steam操作的三個(gè)步驟

      Stream 的操作三個(gè)步驟
      1.創(chuàng)建 Stream
      一個(gè)數(shù)據(jù)源(如:集合、數(shù)組),獲取一個(gè)流
      ? 2.中間操作
      一個(gè)中間操作鏈,對(duì)數(shù)據(jù)源的數(shù)據(jù)進(jìn)行處理
      ? 3.終止操作(終端操作)
      一個(gè)終止操作,執(zhí)行中間操作鏈,并產(chǎn)生結(jié)果

創(chuàng)建Stream的方式

1.Java8 中的 Collection 接口被擴(kuò)展,提供了
  兩個(gè)獲取流的方法:

? default Stream stream() : 返回一個(gè)順序流
? default Stream parallelStream() : 返回一個(gè)并行流
2.Java8 中的 Arrays 的靜態(tài)方法 stream() 可以獲取數(shù)組流:
? static Stream stream(T[] array): 返回一個(gè)流
重載形式,能夠處理對(duì)應(yīng)基本類型的數(shù)組:
public static IntStream stream(int[] array)
? public static LongStream stream(long[] array)
? public static DoubleStream stream(double[] array)
3.由值創(chuàng)建流,可以使用靜態(tài)方法 Stream.of(), 通過(guò)顯示值創(chuàng)建一個(gè)流。它可以接收任意數(shù)量的參數(shù)。
? public static Stream of(T... values) : 返回一個(gè)流
4.由函數(shù)創(chuàng)建流:創(chuàng)建無(wú)限流可以使用靜態(tài)方法 Stream.iterate()和Stream.generate(), 創(chuàng)建無(wú)限流。
public static Stream iterate(final T seed, finalUnaryOperator f) 迭代
public static Stream generate(Supplier s) 生成

Stream 的中間操作

多個(gè)中間操作可以連接起來(lái)形成一個(gè)流水線,除非流水線上觸發(fā)終止操作,否則中間操作不會(huì)執(zhí)行任何的處理!
而在終止操作時(shí)一次性全部處理,稱為“惰性求值”。
    1. 篩選與切片
      filter(Predicate p) 過(guò)濾 接收 Lambda , 從流中排除某些元素。
      distinct() 去重,通過(guò)流所生成元素的 hashCode() 和 equals() 去除重復(fù)元素
      limit(long maxSize) 截?cái)嗔?,使其元素不超過(guò)給定數(shù)量。
      skip(long n) 跳過(guò)元素,返回一個(gè)扔掉了前 n 個(gè)元素的流。若流中元素不足 n 個(gè),則返回一個(gè)空流。與 limit(n) 互補(bǔ)
  • 2.映射
    map(Function f) 接收一個(gè)函數(shù)作為參數(shù),該函數(shù)會(huì)被應(yīng)用到每個(gè)元素上,并將其映射成一個(gè)新的元素。
    flatMap(Function f) 接收一個(gè)函數(shù)作為參數(shù),將流中的每個(gè)值都換成另一個(gè)流,然后把所有流連接成一個(gè)流.
    mapToDouble(ToDoubleFunction f) 接收一個(gè)函數(shù)作為參數(shù),該函數(shù)會(huì)被應(yīng)用到每個(gè)元素上,產(chǎn)生一個(gè)新的 DoubleStream。
    mapToInt(ToIntFunction f) 接收一個(gè)函數(shù)作為參數(shù),該函數(shù)會(huì)被應(yīng)用到每個(gè)元素上,產(chǎn)生一個(gè)新的 IntStream。
    mapToLong(ToLongFunction f) 接收一個(gè)函數(shù)作為參數(shù),該函數(shù)會(huì)被應(yīng)用到每個(gè)元素上,產(chǎn)生一個(gè)新的 LongStream。

  • 3.排序
    sorted() 產(chǎn)生一個(gè)新流,其中按自然順序排序 元素實(shí)現(xiàn)Compareble接口
    sorted(Comparator comp) 產(chǎn)生一個(gè)新流,其中按比較器順序排序 傳入一個(gè)比較器

    steam的終止操作

    終端操作會(huì)從流的流水線生成結(jié)果。其結(jié)果可以是任何不是流的值,例如:List、Integer,甚至是 void 。

1.查找與匹配
    allMatch(Predicate p)   檢查是否匹配所有元素  比如判斷 所有員工的年齡都是17歲 如果有一個(gè)不是,就返回false
    anyMatch(Predicate p)   檢查是否至少匹配一個(gè)元素  比如判斷是否有姓王的員工,如果至少有一個(gè)就返回true
    noneMatch(Predicate p)  檢查是否沒有匹配所有元素   比如判斷所有員工的工資都是否都是高于3000 如果有一個(gè)人低于3000 就返回false
    findFirst()     返回第一個(gè)元素  比如獲取工資最高的人  或者 獲取工資最高的值是
    findAny()       返回當(dāng)前流中的任意元素   比如隨便獲取一個(gè)姓王的員工
    count() 返回流中元素總數(shù)  
    max(Comparator c)   返回流中大值  比如:獲取大年齡值
    min(Comparator c)   返回流中最小值  比如:獲取最小年齡的值
    forEach(Consumer c) 內(nèi)部迭代(使用 Collection 接口需要用戶去做迭代,稱為外部迭代。相反,Stream API 使用內(nèi)部迭代——它幫你把迭代做了)
2.歸約
    reduce(T iden, BinaryOperator b)  參1 是起始值, 參2 二元運(yùn)算  可以將流中元素反復(fù)結(jié)合起來(lái),得到一個(gè)值。返回 T  比如: 求集合中元素的累加總和 
    reduce(BinaryOperator b) 這個(gè)方法沒有起始值  可以將流中元素反復(fù)結(jié)合起來(lái),得到一個(gè)值。返回 Optional  , 比如你可以算所有員工工資的總和
    備注:map 和 reduce 的連接通常稱為 map-reduce 模式,因 Google 用它來(lái)進(jìn)行網(wǎng)絡(luò)搜索而出名。
3.收集
    collect(Collector c)    將流轉(zhuǎn)換為其他形式。接收一個(gè) Collector接口的實(shí)現(xiàn),用于給Stream中元素做匯總的方法
    Collector 接口中方法的實(shí)現(xiàn)決定了如何對(duì)流執(zhí)行收集操作(如收集到 List、Set、Map)。
    但是 Collectors 實(shí)用類提供了很多靜態(tài)方法,可以方便地創(chuàng)建常見收集器實(shí)例,具體方法與實(shí)例如下
 4.Collectors 中的方法
    List toList()        把流中元素收集到List   比如把所有員工的名字通過(guò)map()方法提取出來(lái)之后,在放到List集合中去
        例子:List emps= list.stream().map(提取名字).collect(Collectors.toList());
    Set  toSet()     把流中元素收集到Set  比如把所有員工的名字通過(guò)map()方法提取出來(lái)之后,在放到Set集合中去
        例子:Set emps= list.stream().collect(Collectors.toSet());
    Collection toCollection()        把流中元素收集到創(chuàng)建的集合 比如把所有員工的名字通過(guò)map()方法提取出來(lái)之后,在放到自己指定的集合中去
        例子:Collectionemps=list.stream().map(提取名字).collect(Collectors.toCollection(ArrayList::new));
    Long counting()     計(jì)算流中元素的個(gè)數(shù)
        例子:long count = list.stream().collect(Collectors.counting());
    Integer summingInt()    對(duì)流中元素的整數(shù)屬性求和
        例子:inttotal=list.stream().collect(Collectors.summingInt(Employee::getSalary));
    Double averagingInt()       計(jì)算流中元素Integer屬性的平均值
        例子:doubleavg= list.stream().collect(Collectors.averagingInt(Employee::getSalary));
    IntSummaryStatistics summarizingInt()   收集流中Integer屬性的統(tǒng)計(jì)值。
        例子:DoubleSummaryStatistics dss= list.stream().collect(Collectors.summarizingDouble(Employee::getSalary));
           從DoubleSummaryStatistics 中可以獲取大值,平均值等
                                    double average = dss.getAverage();
                    long count = dss.getCount();
                            double max = dss.getMax();
    String joining() 連接流中每個(gè)字符串  比如把所有人的名字提取出來(lái),在通過(guò)"-"橫杠拼接起來(lái)
        例子:String str= list.stream().map(Employee::getName).collect(Collectors.joining("-"));
    Optional maxBy() 根據(jù)比較器選擇大值  比如求大工資
        例子:Optionalmax= list.stream().collect(Collectors.maxBy(comparingInt(Employee::getSalary)));
    Optional minBy() 根據(jù)比較器選擇最小值  比如求最小工資
        例子:Optional min = list.stream().collect(Collectors.minBy(comparingInt(Employee::getSalary)));
    歸約產(chǎn)生的類型 reducing() 從一個(gè)作為累加器的初始值開始,利用BinaryOperator與流中元素逐個(gè)結(jié)合,從而歸約成單個(gè)值
        例子:inttotal=list.stream().collect(Collectors.reducing(0, Employee::getSalar, Integer::sum));
    轉(zhuǎn)換函數(shù)返回的類型 collectingAndThen()       包裹另一個(gè)收集器,對(duì)其結(jié)果轉(zhuǎn)換函數(shù)
        例子:inthow= list.stream().collect(Collectors.collectingAndThen(Collectors.toList(), List::size));
    Map> groupingBy() 根據(jù)某屬性值對(duì)流分組,屬性為K,結(jié)果為V  比如按照 狀態(tài)分組
        例子:Map> map= list.stream().collect(Collectors.groupingBy(Employee::getStatus));
    Map> partitioningBy() 根據(jù)true或false進(jìn)行分區(qū) 比如 工資大于等于6000的一個(gè)區(qū),小于6000的一個(gè)區(qū)
        例子:Map>vd= list.stream().collect(Collectors.partitioningBy(Employee::getSalary));

并行流與串行流

并行流就是把一個(gè)內(nèi)容分成多個(gè)數(shù)據(jù)塊,并用不同的線程分別處理每個(gè)數(shù)據(jù)塊的流。
Java 8 中將并行進(jìn)行了優(yōu)化,我們可以很容易的對(duì)數(shù)據(jù)進(jìn)行并行操作。
Stream API 可以聲明性地通過(guò) parallel() 與sequential() 在并行流與順序流之間進(jìn)行切換。

列子:

public Employee() {
}

public Employee(String name) {
    this.name = name;
}

public Employee(String name, int age) {
    this.name = name;
    this.age = age;
}

public Employee(int id, String name, int age, double salary) {
    this.id = id;
    this.name = name;
    this.age = age;
    this.salary = salary;
}

public Employee(int id, String name, int age, double salary, Status status) {
    this.id = id;
    this.name = name;
    this.age = age;
    this.salary = salary;
    this.status = status;
}

public Status getStatus() {
    return status;
}

public void setStatus(Status status) {
    this.status = status;
}

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public int getAge() {
    return age;
}

public void setAge(int age) {
    this.age = age;
}

public double getSalary() {
    return salary;
}

public void setSalary(double salary) {
    this.salary = salary;
}

public String show() {
    return "測(cè)試方法引用!";
}

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + age;
    result = prime * result + id;
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    long temp;
    temp = Double.doubleToLongBits(salary);
    result = prime * result + (int) (temp ^ (temp >>> 32));
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Employee other = (Employee) obj;
    if (age != other.age)
        return false;
    if (id != other.id)
        return false;
    if (name == null) {
        if (other.name != null)
            return false;
    } else if (!name.equals(other.name))
        return false;
    if (Double.doubleToLongBits(salary) != Double.doubleToLongBits(other.salary))
        return false;
    return true;
}

@Override
public String toString() {
    return "Employee [id=" + id + ", name=" + name + ", age=" + age + ", salary=" + salary + ", status=" + status
            + "]";
}

//枚舉
public enum Status {
    FREE, //空閑
    BUSY, //繁忙
    VOCATION;//休假
}

}
public class MyTest {
public static void main(String[] args) {
//**Stream 的操作三個(gè)步驟
//1. 創(chuàng)建 Stream
//一個(gè)數(shù)據(jù)源(如:集合、數(shù)組),獲取一個(gè)流
//?2. 中間操作
//一個(gè)中間操作鏈,對(duì)數(shù)據(jù)源的數(shù)據(jù)進(jìn)行處理
//?3. 終止操作(終端操作)
//一個(gè)終止操作,執(zhí)行中間操作鏈,并產(chǎn)生結(jié)果
//我們會(huì)創(chuàng)建流跟集合關(guān)聯(lián)起來(lái),關(guān)聯(lián)起來(lái)后,我們是想要使用這個(gè)流對(duì)集合中的元素,進(jìn)行一些列的中間操作
//1. 篩選與切片
//filter(Predicate p) 過(guò)濾 接收 Lambda ,從流中排除某些元素。
//distinct() 去重,通過(guò)流所生成元素的 hashCode () 和 equals () 去除重復(fù)元素
//limit( long maxSize)截?cái)嗔?,使其元素不超過(guò)給定數(shù)量。
//skip( long n)跳過(guò)元素,返回一個(gè)扔掉了前 n 個(gè)元素的流。若流中元素不足 n 個(gè),則返回一個(gè)空流。與 limit (n) 互補(bǔ)
//

List emps = Arrays.asList(
            new Employee(102, "李四", 59, 6666.66),
            new Employee(101, "張三", 18, 9999.99),
            new Employee(103, "王五", 28, 3333.33),
            new Employee(104, "趙六", 8, 7777.77),
            new Employee(104, "趙六", 8, 7777.77),
            new Employee(104, "趙六", 8, 7777.77),
            new Employee(105, "田七", 38, 5555.55)
    );
    //獲取流跟集合進(jìn)行關(guān)聯(lián)
    Stream stream = emps.stream();
    //那么我們通過(guò)這個(gè)流,對(duì)集合中的元素進(jìn)行一些列的中間操作
    //獲取工資大于6000塊錢的員工
   // Predicate 斷言型接口
    Stream employeeStream = stream.filter((employee) -> employee.getSalary()>6666);
    //終止操作沒有執(zhí)行,其實(shí)中間操作,沒有執(zhí)行
    employeeStream.forEach(System.out::println);
    System.out.println("--------------------------");
    Stream stream2 = emps.stream();
    //我要過(guò)濾出名字是趙六的員工
    stream2.filter((emp)->emp.getName().equals("趙六")).forEach(System.out::println);

}

}
public class MyTest2 {
public static void main(String[] args) {
//distinct() 去重,通過(guò)流所生成元素的 hashCode () 和 equals () 去除重復(fù)元素
List emps = Arrays.asList(
new Employee(102, "李四", 59, 6666.66),
new Employee(101, "張三", 18, 9999.99),
new Employee(103, "王五", 28, 3333.33),
new Employee(104, "趙六", 8, 7777.77),
new Employee(104, "趙六", 8, 7777.77),
new Employee(104, "趙六", 8, 7777.77),
new Employee(105, "田七", 38, 5555.55)
);

Stream stream = emps.stream();
    Stream employeeStream = stream.filter((emp) -> emp.getSalary() > 5000);
    Stream distinct = employeeStream.distinct();
    distinct.forEach(System.out::println);
}

}
public class MyTest3 {
public static void main(String[] args) {
List emps = Arrays.asList(
new Employee(102, "李四", 59, 6666.66),
new Employee(101, "張三", 18, 9999.99),
new Employee(103, "王五", 28, 3333.33),
new Employee(104, "趙六", 8, 7777.771),
new Employee(104, "趙六", 8, 7777.772),
new Employee(104, "趙六", 8, 7777.773),
new Employee(105, "田七", 38, 5555.55)
);

Stream stream = emps.stream();
    Stream stream1 = stream.filter((emp) -> emp.getName().equals("趙六"));
   // Stream limit = stream1.limit(2); //截?cái)嗔?    //skip( long n)跳過(guò)元素,返回一個(gè)扔掉了前 n 個(gè)元素的流。若流中元素不足 n 個(gè),則返回一個(gè)空流。與 limit (n) 互補(bǔ)
    Stream skip = stream1.skip(1);//跳過(guò)前幾個(gè)元素,留下剩下的
    skip.forEach(System.out::println);

}

}

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。


分享文章:JDK新特性-創(chuàng)新互聯(lián)
網(wǎng)站鏈接:http://weahome.cn/article/dooepo.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部