本篇內(nèi)容介紹了“JDK8的新特性詳解”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
@Data @ToString @NoArgsConstructor @AllArgsConstructor public class Student { //名字 private String name; //性別 private String sex; //薪水 private int salary; //年齡 private int age; //星座 private String star; }
將這個集合遍歷,然后依次的判斷,這是最為普通的一種方式。
@Test public void test1(){ //首先創(chuàng)建一個 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); }
通過匿名內(nèi)部類的方法,在內(nèi)部類中添加判斷條件進行篩選,首先創(chuàng)建一個公共接口:
public interface FilterProcess<T> { boolean process(T t); }
接下來通過一個公共函數(shù),對集合以及篩選條件做一個共同方法,篩選到班級里星座是天秤星座的學(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é)果如圖:
但是通過這兩種代碼都是很多,所以java8在這一點上提供了對集合篩選大程度的刪減代碼,就是第三種方法。第三種方法:通過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); }
測試結(jié)果:
[Student(name=九天, sex=男, salary=5000, age=18, star=天秤座)]
但是現(xiàn)在又會有人會問這個問題,我的那個方法中是這樣子的
filterStudent(List<Student> students, FilterProcess<Student> mp)
為什么我的代碼參數(shù)卻是這樣子的呢
filterStudent(list,(e)->e.getStar().equals("天秤座")
其實 -> 這個是一個連接符,左邊代表參數(shù),而右邊代表函數(shù)體(也就是我們說的條件),這個e就是代表 FilterProcess<Student> mp 這個參數(shù)的,只不過我們得java8 中l(wèi)ambda可以給這個參數(shù)附加上了條件,這些條件篩選都是封裝到j(luò)dk8中內(nèi)部類中自己實現(xiàn)的,所以我們只要附加條件就可以了,那個(e)就代表傳了參數(shù)。
@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個方法出來,對比前三個方法,簡單了很多,這就是我們lambda演練的過程。
總結(jié):lambda主要是針對集合中條件的篩選,包括數(shù)組等等。接下來我們介紹Stream API ,這個和Lambda息息相關(guān),論重要性,lambda只是基礎(chǔ),Stream API 才是真正的升級版
父類:BasicStream
子類:Stream、IntStream、LongStream、DoubleStream
包含兩個類型,中間操作(intermediate operations)和結(jié)束操作(terminal operations)
下面是所有方法的屬于那一端操作的方法:
然后準(zhǔn)備一個測試類,和一個靜態(tài)變量,圖下:
public class JdkTest { public static List<Student> list = Arrays.asList( new Student("九天", "男", 5000, 18, "天秤座"), new Student("十夜", "男", 4000, 16, "雙魚座"), new Student("十一郎", "男", 3000, 24, "水瓶座") ); }
接下來我們一個一個方法解析他們的作用
將集合轉(zhuǎn)換成流,一般會使用流繼續(xù)后續(xù)操作。
@Test public void test0() { list.stream(); }
forEach遍歷集合,System.out::println等同于System.out.println()
@Test public void test1() { list.forEach(System.out::println); }
結(jié)果為:
該方法中是一個篩選條件,等同于sql查詢的where后面的篩選。
@Test public void test2() { list.stream().filter((e) -> e.getStar().equals("天秤座")) .forEach(System.out::println); }
將List<Student> 轉(zhuǎn)換為List<String>, collect是將結(jié)果轉(zhuǎn)換為List
@Test public void test3() { List<String> names = list.stream().map(Student::getName).collect(Collectors.toList()); names.stream().forEach(System.out::println); }
結(jié)果:
轉(zhuǎn)換數(shù)值流,等同mapToLong、mapToDouble,如下這個是取大值
@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
將流中的每一個元素 T 映射為一個流,再把每一個流連接成為一個流
@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]
@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
@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=雙魚座)
@Test public void test8() { list.stream().skip(1).forEach(System.out::println); }
@Test public void test10() { list.stream().limit(1).forEach(System.out::println); }
結(jié)果為:
Student(name=九天, sex=男, salary=5000, age=18, star=天秤座)
只要有其中任意一個符合條件
@Test public void test11() { boolean isHave = list.stream().anyMatch(student -> student.getAge() == 16); System.out.println(isHave); }
全部符合
@Test public void test12() { boolean isHave = list.stream().allMatch(student -> student.getAge() == 16); System.out.println(isHave); }
是否滿足沒有符合的
@Test public void test13() { boolean isHave = list.stream().noneMatch(student -> student.getAge() == 16); System.out.println(isHave); }
找到其中一個元素 (使用 stream() 時找到的是第一個元素;使用 parallelStream() 并行時找到的是其中一個元素)
@Test public void test14() { Optional<Student> student = list.stream().findAny(); System.out.println(student.get()); }
找到第一個元素
@Test public void test15() { Optional<Student> student = list.stream().findFirst(); System.out.println(student.get()); }
2.17、count計數(shù)
@Test public void test17() { long count = list.stream().count(); System.out.println(count); }
生成一個字符串流
@Test public void test18() { Stream<String> stringStream = Stream.of("i","love","you"); }
生成一個空流
@Test public void test19() { Stream<String> stringStream = Stream.empty(); }
@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)); }); }
1、所有的日期類都是可變的,因此他們都不是線程安全的,這是Java日期類大的問題之一 2、Java的日期/時間類的定義并不一致,在java.util和java.sql的包中都有日期類,此外用于格式化和解析的類在java.text包中定義 3、java.util.Date同時包含日期和時間,而java.sql.Date僅包含日期,將其納入java.sql包并不合理。另外這兩個類都有相同的名字,這本身就是一個非常糟糕的設(shè)計。對于時間、時間戳、格式化以及解析,并沒有一些明確定義的類。對于格式化和解析的需求,我們有java.text.DateFormat抽象類,但通常情況下,SimpleDateFormat類被用于此類需求 4、日期類并不提供國際化,沒有時區(qū)支持,因此Java引入了java.util.Calendar和java.util.TimeZone類,但他們同樣存在上述所有的問題
1、不變性:新的日期/時間API中,所有的類都是不可變的,這對多線程環(huán)境有好處。 2、關(guān)注點分離:新的API將人可讀的日期時間和機器時間(unix timestamp)明確分離,它為日期(Date)、時間(Time)、日期時間(DateTime)、時間戳(unix timestamp)以及時區(qū)定義了不同的類。 3、清晰:在所有的類中,方法都被明確定義用以完成相同的行為。舉個例子,要拿到當(dāng)前實例我們可以使用now()方法,在所有的類中都定義了format()和parse()方法,而不是像以前那樣專門有一個獨立的類。為了更好的處理問題,所有的類都使用了工廠模式和策略模式,一旦你使用了其中某個類的方法,與其他類協(xié)同工作并不困難。 4、實用操作:所有新的日期/時間API類都實現(xiàn)了一系列方法用以完成通用的任務(wù),如:加、減、格式化、解析、從日期/時間中提取單獨部分,等等。 5、可擴展性:新的日期/時間API是工作在ISO-8601日歷系統(tǒng)上的,但我們也可以將其應(yīng)用在非IOS的日歷上。
Java.time包中的是類是不可變且線程安全的。新的時間及日期API位于java.time中,java8 time包下關(guān)鍵字段解讀。
屬性 | 含義 |
Instant | 代表的是時間戳 |
LocalDate | 代表日期,比如2020-01-14 |
LocalTime | 代表時刻,比如12:59:59 |
LocalDateTime | 代表具體時間 2020-01-12 12:22:26 |
ZonedDateTime | 代表一個包含時區(qū)的完整的日期時間,偏移量是以UTC/ 格林威治時間為基準(zhǔn)的 |
Period | 代表時間段 |
ZoneOffset | 代表時區(qū)偏移量,比如:+8:00 |
Clock | 代表時鐘,比如獲取目前美國紐約的時間 |
Instant instant = Instant.now(); //獲取當(dāng)前時間戳 LocalDate localDate = LocalDate.now(); //獲取當(dāng)前日期 LocalTime localTime = LocalTime.now(); //獲取當(dāng)前時刻 LocalDateTime localDateTime = LocalDateTime.now(); //獲取當(dāng)前具體時間 ZonedDateTime zonedDateTime = ZonedDateTime.now(); //獲取帶有時區(qū)的時間
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(); }
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()方法返回在指定時區(qū)從此Instant生成的ZonedDateTime。 LocalDate localDate = instant.atZone(zoneId).toLocalDate(); System.out.println("Date = " + date); System.out.println("LocalDate = " + localDate); } }
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); } }
long timestamp = System.currentTimeMillis(); Instant instant = Instant.ofEpochMilli(timestamp); LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
LocalDateTime dateTime = LocalDateTime.now(); dateTime.toInstant(ZoneOffset.ofHours(8)).toEpochMilli(); dateTime.toInstant(ZoneOffset.of("+08:00")).toEpochMilli(); dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
getYear() int 獲取當(dāng)前日期的年份 getMonth() Month 獲取當(dāng)前日期的月份對象 getMonthValue() int 獲取當(dāng)前日期是第幾月 getDayOfWeek() DayOfWeek 表示該對象表示的日期是星期幾 getDayOfMonth() int 表示該對象表示的日期是這個月第幾天 getDayOfYear() int 表示該對象表示的日期是今年第幾天 withYear(int year) LocalDate 修改當(dāng)前對象的年份 withMonth(int month) LocalDate 修改當(dāng)前對象的月份 withDayOfMonth(intdayOfMonth) LocalDate 修改當(dāng)前對象在當(dāng)月的日期 isLeapYear() boolean 是否是閏年 lengthOfMonth() int 這個月有多少天 lengthOfYear() int 該對象表示的年份有多少天(365或者366) plusYears(longyearsToAdd) LocalDate 當(dāng)前對象增加指定的年份數(shù) plusMonths(longmonthsToAdd) LocalDate 當(dāng)前對象增加指定的月份數(shù) plusWeeks(longweeksToAdd) LocalDate 當(dāng)前對象增加指定的周數(shù) plusDays(longdaysToAdd) LocalDate 當(dāng)前對象增加指定的天數(shù) minusYears(longyearsToSubtract) LocalDate 當(dāng)前對象減去指定的年數(shù) minusMonths(longmonthsToSubtract) LocalDate 當(dāng)前對象減去注定的月數(shù) minusWeeks(longweeksToSubtract) LocalDate 當(dāng)前對象減去指定的周數(shù) minusDays(longdaysToSubtract) LocalDate 當(dāng)前對象減去指定的天數(shù) compareTo(ChronoLocalDateother) int 比較當(dāng)前對象和other對象在時間上的大小,返回值如果為正,則當(dāng)前對象時間較晚, isBefore(ChronoLocalDateother) boolean 比較當(dāng)前對象日期是否在other對象日期之前 isAfter(ChronoLocalDateother) boolean 比較當(dāng)前對象日期是否在other對象日期之后 isEqual(ChronoLocalDateother) boolean 比較兩個日期對象是否相等
“JDK8的新特性詳解”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!
本文標(biāo)題:JDK8的新特性詳解-創(chuàng)新互聯(lián)
URL分享:http://www.rwnh.cn/article18/pdedp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序、網(wǎng)站改版、靜態(tài)網(wǎng)站、網(wǎng)站制作、網(wǎng)站導(dǎo)航、微信公眾號
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容