JDK8的新特性詳解

本篇內(nèi)容介紹了“JDK8的新特性詳解”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

創(chuàng)新互聯(lián)建站專注于澧縣企業(yè)網(wǎng)站建設(shè),自適應(yīng)網(wǎng)站建設(shè),商城網(wǎng)站定制開發(fā)。澧縣網(wǎng)站建設(shè)公司,為澧縣等地區(qū)提供建站服務(wù)。全流程定制網(wǎng)站設(shè)計(jì),專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)建站專業(yè)和態(tài)度為您提供的服務(wù)

1、Lambda演變過程

@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    //名字
    private String name;
    //性別
    private String sex;
    //薪水
    private int salary;
    //年齡
    private int age;
    //星座
    private String star;
}
1.1、普通篩選

      將這個(gè)集合遍歷,然后依次的判斷,這是最為普通的一種方式。

@Test
public void test1(){
    //首先創(chuàng)建一個(gè)
    List<Student> list = Arrays.asList(
            new Student("九天","男",5000,18,"天秤座"),
            new Student("十夜","男",4000,16,"雙魚座"),
            new Student("十一郎","男",3000,24,"水瓶座")
    );
    List<Student> result = new ArrayList<>();
    for (Student student:list){
        if ("天秤座".equals(student.getStar())){
            result.add(student);
        }
    }
    System.out.println(result);
}
1.2、匿名內(nèi)部類篩選

      通過匿名內(nèi)部類的方法,在內(nèi)部類中添加判斷條件進(jìn)行篩選,首先創(chuàng)建一個(gè)公共接口:

public interface FilterProcess<T> {
    boolean process(T t);
}

      接下來通過一個(gè)公共函數(shù),對(duì)集合以及篩選條件做一個(gè)共同方法,篩選到班級(jí)里星座是天秤星座的學(xué)生

public List<Student> filterStudent(List<Student> students, FilterProcess<Student> mp){
    List<Student> list = new ArrayList<>();
    for (Student student : students) {
        if(mp.process(student)){
            list.add(student);
        }
    }
    return list;
}

      最后是通過匿名內(nèi)部類和該方法得到結(jié)果:

@Test
public void test2(){
    List<Student> students = Arrays.asList(
            new Student("九天","男",5000,18,"天秤座"),
            new Student("十夜","男",4000,16,"雙魚座"),
            new Student("十一郎","男",3000,24,"水瓶座")
    );
    List<Student> list = filterStudent(students, new FilterProcess<Student>() {
        @Override
        public boolean process(Student student) {
            return student.getStar().equals("天秤座");
        }
    });
    for (Student student : list) {
        System.out.println(student);
    }
}

結(jié)果如圖:

JDK8的新特性詳解

1.3、半Lambda方法

      但是通過這兩種代碼都是很多,所以java8在這一點(diǎn)上提供了對(duì)集合篩選最大程度的刪減代碼,就是第三種方法。第三種方法:通過Lambda直接判斷,一步到位,不需要在寫其他的方法。

@Test
public void test3(){
    List<Student> list = Arrays.asList(
            new Student("九天","男",5000,18,"天秤座"),
            new Student("十夜","男",4000,16,"雙魚座"),
            new Student("十一郎","男",3000,24,"水瓶座")
    );
    List<Student> result = filterStudent(list,(e)->e.getStar().equals("天秤座"));
    System.out.println(result);
}

      測(cè)試結(jié)果:

[Student(name=九天, sex=男, salary=5000, age=18, star=天秤座)]

      但是現(xiàn)在又會(huì)有人會(huì)問這個(gè)問題,我的那個(gè)方法中是這樣子的

filterStudent(List<Student> students, FilterProcess<Student> mp)

      為什么我的代碼參數(shù)卻是這樣子的呢

filterStudent(list,(e)->e.getStar().equals("天秤座")

      其實(shí) -> 這個(gè)是一個(gè)連接符,左邊代表參數(shù),而右邊代表函數(shù)體(也就是我們說的條件),這個(gè)e就是代表  FilterProcess<Student> mp 這個(gè)參數(shù)的,只不過我們得java8 中l(wèi)ambda可以給這個(gè)參數(shù)附加上了條件,這些條件篩選都是封裝到j(luò)dk8中內(nèi)部類中自己實(shí)現(xiàn)的,所以我們只要附加條件就可以了,那個(gè)(e)就代表傳了參數(shù)。

1.4、真正運(yùn)用lambda方法
@Test
public void test1() {
    List<Student> list = Arrays.asList(
            new Student("九天","男",5000,18,"天秤座"),
            new Student("十夜","男",4000,16,"雙魚座"),
            new Student("十一郎","男",3000,24,"水瓶座")
    );
    list.stream().filter((e) -> e.getStar().equals("天秤座"))
            .forEach(System.out::println);
}

      結(jié)果依然是相同的答案,直到第4個(gè)方法出來,對(duì)比前三個(gè)方法,簡(jiǎn)單了很多,這就是我們lambda演練的過程。

      總結(jié):lambda主要是針對(duì)集合中條件的篩選,包括數(shù)組等等。接下來我們介紹Stream API ,這個(gè)和Lambda息息相關(guān),論重要性,lambda只是基礎(chǔ),Stream API 才是真正的升級(jí)版

2、StreamAPI詳解

JDK8的新特性詳解

2.0、功能 

      父類:BasicStream

      子類:Stream、IntStream、LongStream、DoubleStream

      包含兩個(gè)類型,中間操作(intermediate operations)和結(jié)束操作(terminal operations)

      下面是所有方法的屬于那一端操作的方法:

              JDK8的新特性詳解

      然后準(zhǔn)備一個(gè)測(cè)試類,和一個(gè)靜態(tài)變量,圖下:

public class JdkTest {
    public static List<Student> list = Arrays.asList(
            new Student("九天", "男", 5000, 18, "天秤座"),
            new Student("十夜", "男", 4000, 16, "雙魚座"),
            new Student("十一郎", "男", 3000, 24, "水瓶座")
    );
}

      接下來我們一個(gè)一個(gè)方法解析他們的作用

2.1、stream

      將集合轉(zhuǎn)換成流,一般會(huì)使用流繼續(xù)后續(xù)操作。

@Test
public void test0() {
    list.stream();
}
2.2、forEach遍歷

      forEach遍歷集合,System.out::println等同于System.out.println()

@Test
public void test1() {
    list.forEach(System.out::println);
}

      結(jié)果為:

JDK8的新特性詳解

2.3、filter過濾

      該方法中是一個(gè)篩選條件,等同于sql查詢的where后面的篩選。

@Test
public void test2() {
    list.stream().filter((e) -> e.getStar().equals("天秤座"))
            .forEach(System.out::println);
}

    JDK8的新特性詳解

2.4、map轉(zhuǎn)換集合

      將List<Student> 轉(zhuǎn)換為L(zhǎng)ist<String>, collect是將結(jié)果轉(zhuǎn)換為L(zhǎng)ist

@Test
public void test3() {
    List<String> names = list.stream().map(Student::getName).collect(Collectors.toList());
    names.stream().forEach(System.out::println);
}

      結(jié)果:

      JDK8的新特性詳解

2.5、mapToInt轉(zhuǎn)換數(shù)值流

      轉(zhuǎn)換數(shù)值流,等同mapToLong、mapToDouble,如下這個(gè)是取最大值

@Test
public void test4() {
    IntStream intStream = list.stream().mapToInt(Student::getAge);
    Stream<Integer> integerStream = intStream.boxed();
    Optional<Integer> max   = integerStream.max(Integer::compareTo);
    System.out.println(max.get());
}

      結(jié)果為:

24
2.6、flatMap合并成一個(gè)流

      將流中的每一個(gè)元素 T 映射為一個(gè)流,再把每一個(gè)流連接成為一個(gè)流

@Test
public void test5() {
    List<String> list2 = new ArrayList<>();
    list2.add("aaa bbb ccc");
    list2.add("ddd eee fff");
    list2.add("ggg hhh iii");
    list2 = list2.stream().map(s -> s.split(" ")).flatMap(Arrays::stream).collect(Collectors.toList());
    System.out.println(list2);
}

      結(jié)果為:

[aaa, bbb, ccc, ddd, eee, fff, ggg, hhh, iii]
2.7、distinct去重
@Test
public void test6() {
    List<String> list2 = new ArrayList<>();
    list2.add("aaa bbb ccc");
    list2.add("ddd eee fff");
    list2.add("ggg hhh iii");
    list2.add("ggg hhh iii");
    list2.stream().distinct().forEach(System.out::println);
}

      結(jié)果:

aaa bbb ccc
ddd eee fff
ggg hhh iii
2.8、sorted排序
@Test
public void test7() {
    //asc排序
    list.stream().sorted(Comparator.comparingInt(Student::getAge)).forEach(System.out::println);
    System.out.println("------------------------------------------------------------------");
    //desc排序
    list.stream().sorted(Comparator.comparingInt(Student::getAge).reversed()).forEach(System.out::println);
}

      結(jié)果:

Student(name=十夜, sex=男, salary=4000, age=16, star=雙魚座)
Student(name=九天, sex=男, salary=5000, age=18, star=天秤座)
Student(name=十一郎, sex=男, salary=3000, age=24, star=水瓶座)
------------------------------------------------------------------
Student(name=十一郎, sex=男, salary=3000, age=24, star=水瓶座)
Student(name=九天, sex=男, salary=5000, age=18, star=天秤座)
Student(name=十夜, sex=男, salary=4000, age=16, star=雙魚座)
2.9、skip跳過前n個(gè)
@Test
public void test8() {
    list.stream().skip(1).forEach(System.out::println);
}
2.10、limit截取前n個(gè)
@Test
public void test10() {
    list.stream().limit(1).forEach(System.out::println);
}

      結(jié)果為:

Student(name=九天, sex=男, salary=5000, age=18, star=天秤座)
2.11、anyMatch

      只要有其中任意一個(gè)符合條件

@Test
public void test11() {
    boolean isHave = list.stream().anyMatch(student -> student.getAge() == 16);
    System.out.println(isHave);
}
2.12、allMatch

      全部符合

@Test
public void test12() {
    boolean isHave = list.stream().allMatch(student -> student.getAge() == 16);
    System.out.println(isHave);
}
2.13、noneMatch

      是否滿足沒有符合的

@Test
public void test13() {
    boolean isHave = list.stream().noneMatch(student -> student.getAge() == 16);
    System.out.println(isHave);
}
2.14、findAny

      找到其中一個(gè)元素 (使用 stream() 時(shí)找到的是第一個(gè)元素;使用 parallelStream() 并行時(shí)找到的是其中一個(gè)元素)

@Test
public void test14() {
    Optional<Student> student = list.stream().findAny();
    System.out.println(student.get());
}
2.15、findFirst

      找到第一個(gè)元素

@Test
public void test15() {
    Optional<Student> student = list.stream().findFirst();
    System.out.println(student.get());
}

2.17、count計(jì)數(shù)

@Test
public void test17() {
    long count = list.stream().count();
    System.out.println(count);
}
2.18、of

      生成一個(gè)字符串流

@Test
public void test18() {
    Stream<String> stringStream = Stream.of("i","love","you");
}
2.19、empty

      生成一個(gè)空流

@Test
public void test19() {
    Stream<String> stringStream = Stream.empty();
}
2.20、iterate
@Test
public void test20() {
    List<String> list = Arrays.asList("a", "b", "c", "c", "d", "f", "a");
    Stream.iterate(0, i -> i + 1).limit(list.size()).forEach(i -> {
        System.out.println(String.valueOf(i) + list.get(i));
    });
}

3、Date

3.1、JDK7 Date缺點(diǎn)
1、所有的日期類都是可變的,因此他們都不是線程安全的,這是Java日期類最大的問題之一
2、Java的日期/時(shí)間類的定義并不一致,在java.util和java.sql的包中都有日期類,此外用于格式化和解析的類在java.text包中定義
3、java.util.Date同時(shí)包含日期和時(shí)間,而java.sql.Date僅包含日期,將其納入java.sql包并不合理。另外這兩個(gè)類都有相同的名字,這本身就是一個(gè)非常糟糕的設(shè)計(jì)。對(duì)于時(shí)間、時(shí)間戳、格式化以及解析,并沒有一些明確定義的類。對(duì)于格式化和解析的需求,我們有java.text.DateFormat抽象類,但通常情況下,SimpleDateFormat類被用于此類需求
4、日期類并不提供國(guó)際化,沒有時(shí)區(qū)支持,因此Java引入了java.util.Calendar和java.util.TimeZone類,但他們同樣存在上述所有的問題
3.2、JDK8 Date優(yōu)勢(shì)
1、不變性:新的日期/時(shí)間API中,所有的類都是不可變的,這對(duì)多線程環(huán)境有好處。
2、關(guān)注點(diǎn)分離:新的API將人可讀的日期時(shí)間和機(jī)器時(shí)間(unix timestamp)明確分離,它為日期(Date)、時(shí)間(Time)、日期時(shí)間(DateTime)、時(shí)間戳(unix timestamp)以及時(shí)區(qū)定義了不同的類。
3、清晰:在所有的類中,方法都被明確定義用以完成相同的行為。舉個(gè)例子,要拿到當(dāng)前實(shí)例我們可以使用now()方法,在所有的類中都定義了format()和parse()方法,而不是像以前那樣專門有一個(gè)獨(dú)立的類。為了更好的處理問題,所有的類都使用了工廠模式和策略模式,一旦你使用了其中某個(gè)類的方法,與其他類協(xié)同工作并不困難。
4、實(shí)用操作:所有新的日期/時(shí)間API類都實(shí)現(xiàn)了一系列方法用以完成通用的任務(wù),如:加、減、格式化、解析、從日期/時(shí)間中提取單獨(dú)部分,等等。
5、可擴(kuò)展性:新的日期/時(shí)間API是工作在ISO-8601日歷系統(tǒng)上的,但我們也可以將其應(yīng)用在非IOS的日歷上。
3.3、JDK8 Date新增字段

      Java.time包中的是類是不可變且線程安全的。新的時(shí)間及日期API位于java.time中,java8 time包下關(guān)鍵字段解讀。

屬性含義
Instant 代表的是時(shí)間戳
LocalDate 代表日期,比如2020-01-14
LocalTime 代表時(shí)刻,比如12:59:59
LocalDateTime 代表具體時(shí)間 2020-01-12 12:22:26
ZonedDateTime 代表一個(gè)包含時(shí)區(qū)的完整的日期時(shí)間,偏移量是以UTC/  格林威治時(shí)間為基準(zhǔn)的
Period 代表時(shí)間段
ZoneOffset 代表時(shí)區(qū)偏移量,比如:+8:00
Clock 代表時(shí)鐘,比如獲取目前美國(guó)紐約的時(shí)間
3.4、獲取當(dāng)前時(shí)間
Instant instant = Instant.now(); //獲取當(dāng)前時(shí)間戳
LocalDate localDate = LocalDate.now();  //獲取當(dāng)前日期
LocalTime localTime = LocalTime.now();  //獲取當(dāng)前時(shí)刻
LocalDateTime localDateTime = LocalDateTime.now();  //獲取當(dāng)前具體時(shí)間
ZonedDateTime zonedDateTime = ZonedDateTime.now();   //獲取帶有時(shí)區(qū)的時(shí)間
3.5、字符串轉(zhuǎn)換
jdk8:
String str = "2019-01-11";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate localDate = LocalDate.parse(str, formatter);
jdk7:
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
    Date date = simpleDateFormat.parse(str); 
} catch (ParseException e){ 
    e.printStackTrace();
}
3.6、Date轉(zhuǎn)換LocalDate
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
public class Test {
    public static void main(String[] args) {
        Date date = new Date();
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        // atZone()方法返回在指定時(shí)區(qū)從此Instant生成的ZonedDateTime。
        LocalDate localDate = instant.atZone(zoneId).toLocalDate();
        System.out.println("Date = " + date);
        System.out.println("LocalDate = " + localDate);
    }
}
3.7、LocalDate轉(zhuǎn)Date
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
public class Test {
    public static void main(String[] args) {
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDate localDate = LocalDate.now();
        ZonedDateTime zdt = localDate.atStartOfDay(zoneId);
        Date date = Date.from(zdt.toInstant());
        System.out.println("LocalDate = " + localDate);
        System.out.println("Date = " + date);
    }
}
3.8、時(shí)間戳轉(zhuǎn)LocalDateTime
long timestamp = System.currentTimeMillis();
Instant instant = Instant.ofEpochMilli(timestamp);
LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
3.9、LocalDateTime轉(zhuǎn)時(shí)間戳
LocalDateTime dateTime = LocalDateTime.now();
dateTime.toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
dateTime.toInstant(ZoneOffset.of("+08:00")).toEpochMilli();
dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
3.10、LocalDate方法總結(jié)
getYear()                         int        獲取當(dāng)前日期的年份
getMonth()                        Month      獲取當(dāng)前日期的月份對(duì)象
getMonthValue()                   int        獲取當(dāng)前日期是第幾月
getDayOfWeek()                    DayOfWeek  表示該對(duì)象表示的日期是星期幾
getDayOfMonth()                   int        表示該對(duì)象表示的日期是這個(gè)月第幾天
getDayOfYear()                    int        表示該對(duì)象表示的日期是今年第幾天
withYear(int year)                LocalDate  修改當(dāng)前對(duì)象的年份
withMonth(int month)              LocalDate  修改當(dāng)前對(duì)象的月份
withDayOfMonth(intdayOfMonth)     LocalDate  修改當(dāng)前對(duì)象在當(dāng)月的日期
isLeapYear()                      boolean    是否是閏年
lengthOfMonth()                   int        這個(gè)月有多少天
lengthOfYear()                    int        該對(duì)象表示的年份有多少天(365或者366)
plusYears(longyearsToAdd)         LocalDate  當(dāng)前對(duì)象增加指定的年份數(shù)
plusMonths(longmonthsToAdd)       LocalDate  當(dāng)前對(duì)象增加指定的月份數(shù)
plusWeeks(longweeksToAdd)         LocalDate  當(dāng)前對(duì)象增加指定的周數(shù)
plusDays(longdaysToAdd)           LocalDate  當(dāng)前對(duì)象增加指定的天數(shù)
minusYears(longyearsToSubtract)   LocalDate  當(dāng)前對(duì)象減去指定的年數(shù)
minusMonths(longmonthsToSubtract) LocalDate  當(dāng)前對(duì)象減去注定的月數(shù)
minusWeeks(longweeksToSubtract)   LocalDate  當(dāng)前對(duì)象減去指定的周數(shù)
minusDays(longdaysToSubtract)     LocalDate  當(dāng)前對(duì)象減去指定的天數(shù)
compareTo(ChronoLocalDateother)   int        比較當(dāng)前對(duì)象和other對(duì)象在時(shí)間上的大小,返回值如果為正,則當(dāng)前對(duì)象時(shí)間較晚,
isBefore(ChronoLocalDateother)    boolean    比較當(dāng)前對(duì)象日期是否在other對(duì)象日期之前
isAfter(ChronoLocalDateother)     boolean    比較當(dāng)前對(duì)象日期是否在other對(duì)象日期之后
isEqual(ChronoLocalDateother)     boolean    比較兩個(gè)日期對(duì)象是否相等

“JDK8的新特性詳解”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

新聞標(biāo)題:JDK8的新特性詳解
標(biāo)題路徑:http://muchs.cn/article48/pissep.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供做網(wǎng)站、網(wǎng)站設(shè)計(jì)公司、網(wǎng)站維護(hù)、外貿(mào)網(wǎng)站建設(shè)、企業(yè)建站、虛擬主機(jī)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

營(yíng)銷型網(wǎng)站建設(shè)