日期-時間
LocalDateTime
/**
* LocalDateTime
* 獲取本地日期時間物件:年-月-日T時:分:秒.納秒
* LocalDateTime.now();獲取當前日期
* LocalDateTime.of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond);獲取指定日期
* 注意:LocalDateTime()修改日期,不會將原有日期修改,會返回一個新的日期物件
* 注意字首
* with:直接修改某個資訊
* plus:將某個資訊新增多少
* minus:將某個資訊減多少
* to:轉換為某個日期或這時間物件
*
* isAfter():判斷某個時間是否在某一時間之後
* isBefore():判斷某個時間是否在某一時間之前
* equals():判斷兩個時間是否相等
*/
@Test
void testLocalDateTime(){
//獲取本地日期和時間物件:年-月-日T時:分:秒.納秒 2023-07-14T15:21:00.524
LocalDateTime now = LocalDateTime.now();
LocalDateTime of = LocalDateTime.of(2000, 06, 16, 8, 15, 22, 232322);
System.out.println(now);
System.out.println(now.getDayOfMonth());//某月的第幾天
System.out.println(now.getMonth());//某月英文
System.out.println(now.getMonthValue());//某月的數值
System.out.println(now.getDayOfWeek().getValue());//星期幾
System.out.println(now.withMonth(10));//修改月份為10,並且返回這個物件
System.out.println(now.plusMonths(2));//月份新增2
System.out.println(now.minusYears(3));//年份減少3
System.out.println("-------");
System.out.println(now.getHour());//獲取當前小時
System.out.println(now.getMinute());//獲取當前分鐘
System.out.println(now.getSecond());//獲取當前秒數
System.out.println(now.getNano());//獲取當前納秒
System.out.println(now.withHour(22));//修改小時為22
System.out.println(now.plusMinutes(12));//分鐘加12
System.out.println(now.minusSeconds(12));//秒數減12
System.out.println("-------");
System.out.println(now);
System.out.println(of);
System.out.println("------");
System.out.println(now.isAfter(of));
System.out.println(now.isBefore(of));
System.out.println(now.equals(of));
LocalDate localDate = now.toLocalDate();//轉換為日期物件
System.out.println(localDate);
LocalTime localTime = now.toLocalTime();//轉換為時間物件
System.out.println(localTime);
}
結果如下:
2023-07-14T15:41:28.009
14
JULY
7
5
2023-10-14T15:41:28.009
2023-09-14T15:41:28.009
2020-07-14T15:41:28.009
-------
15
41
28
9000000
2023-07-14T22:41:28.009
2023-07-14T15:53:28.009
2023-07-14T15:41:16.009
-------
2023-07-14T15:41:28.009
2000-06-16T08:15:22.000232322
------
true
false
false
2023-07-14
15:41:28.009
2023-07-14T15:41:28.009
Process finished with exit code 0
LocalDate
/**
* LocalDate
* 獲取本地日期物件:年-月-日
* LocalDate.now();獲取當前日期
* LocalDate.of(year,month,dayOfMonth);獲取指定日期
* 注意:LocalDate()修改日期,不會將原有日期修改,會返回一個新的日期物件
* 注意字首
* with:修改某個資訊
* plus:將某個資訊新增多少
* minus:將某個資訊減多少
* isAfter():判斷某個日期是否在某一日期之後
* isBefore():判斷某個日期是否在某一日期之前
* equals():判斷兩個日期是否相等
*/
@Test
void testLocalDate(){
//獲取本地日期物件:年-月-日
LocalDate now = LocalDate.now();
System.out.println(now);//2023-07-14
System.out.println(now.getDayOfMonth());//某月的第幾天
System.out.println(now.getMonth());//某月英文
System.out.println(now.getMonthValue());//某月的數值
System.out.println(now.getDayOfWeek().getValue());//星期幾
System.out.println(now.withMonth(10));//修改月份為10,並且返回這個物件
System.out.println(now.plusMonths(2));//月份新增2
System.out.println(now.minusYears(3));//年份減少3
System.out.println("-------");
LocalDate of = LocalDate.of(2000, 5, 27);//獲取指定的日期物件
System.out.println(of);
System.out.println(now.isAfter(of));
System.out.println(now.isBefore(of));
System.out.println(now.equals(of));
}
結果如下:
LocalTime
/**
*
* LocalTime
* 獲取本地時間物件:時:分:秒.納秒
* LocalTime.now();獲取當前時間
* LocalTime.of(int hour, int minute, int second, int nanoOfSecond);獲取指定時間
* 注意:LocalTime()修改時間,不會將原有時間修改,會返回一個新的時間物件
* 注意字首
* with:直接修改某個資訊
* plus:將某個資訊新增多少
* minus:將某個資訊減多少
* isAfter():判斷某個時間是否在某一時間之後
* isBefore():判斷某個時間是否在某一時間之前
* equals():判斷兩個時間是否相等
*/
@Test
void testLocalTime(){
//獲取本地時間物件:時:分:秒.納秒
LocalTime now = LocalTime.now();
LocalTime of = LocalTime.of(22, 30, 33, 6666);
System.out.println(now);//獲取當前時間
System.out.println(now.getHour());//獲取當前小時
System.out.println(now.getMinute());//獲取當前分鐘
System.out.println(now.getSecond());//獲取當前秒數
System.out.println(now.getNano());//獲取當前納秒
System.out.println(now.withHour(22));//修改小時為22
System.out.println(now.plusMinutes(12));//分鐘加12
System.out.println(now.minusSeconds(12));//秒數減12
System.out.println("------");
System.out.println(of);
System.out.println(now.isAfter(of));//now在of之前?
System.out.println(now.isBefore(of));//now在of之後?
System.out.println(now.equals(of));//now和of是否相等
}
結果如下:
ZoneId ZonedDateTime
/**
* ZoneId ZonedDateTime
* 時區
* ZonedDateTime與LocalDateTime中獲取日期時間的方法基本一致
*/
@Test
void testZoneId(){
ZoneId zoneId = ZoneId.systemDefault();
System.out.println(zoneId.getId());//獲取當前系統預設時區
System.out.println(zoneId);//相當與呼叫該toString()方法,在這個方法中又呼叫了getId();
// System.out.println(ZoneId.getAvailableZoneIds());//獲取Java支援的全部時區Id
ZoneId zoneId1 = ZoneId.of("America/New_York");//將某個時區id封裝成ZoneId物件
ZonedDateTime now = ZonedDateTime.now(zoneId);//獲取某個時區的ZonedDateTime物件
System.out.println(now);
ZonedDateTime now1 = ZonedDateTime.now(Clock.systemUTC());//世界標準時間
System.out.println(now1);
System.out.println(ZonedDateTime.now());//系統預設時區的時間
}
Instant
/**
* Instant
* 透過獲取Instant的物件可以拿到此刻的時間,該時間由兩部分組成:從1970-01-01 00:00:00開始走到此刻的總秒數+不夠1秒的納秒數
*
* 通常用來做程式碼的效能分析,或者記錄使用者的操作時間點
* 作用:可以用來記錄程式碼的執行時間,或用於記錄使用者操作的某個事件的時間點
*/
@Test
void testInstant(){
Instant now = Instant.now();//不可變物件
System.out.println(now);
System.out.println(now.getEpochSecond());//獲取總秒數
System.out.println(now.getNano());//不夠一秒的納秒數
System.out.println(now.plusMillis(111));//納秒加111
}
DateTimeFormatter
/**
* DateTimeFormatter
* 時間格式化器
*/
@Test
void testDateTimeFormatter(){
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");//建立時間格式化器物件
System.out.println(dateTimeFormatter);
LocalDateTime now = LocalDateTime.now();//對時間進行格式化
System.out.println(now);
System.out.println(dateTimeFormatter.format(now));//dateTimeFormatter物件對時間物件now進行格式化
System.out.println(now.format(dateTimeFormatter));//now物件使用dateTimeFormatter時間格式化器進行格式化
// 解析時間2000年03月23日 17:14:07
LocalDateTime parse = LocalDateTime.parse("2000年03月23日 17:14:07", dateTimeFormatter);
System.out.println(parse);
}
Period
/**
* Period(一段時期)LocalDate
* 用於計算兩個LocalDate物件 香腸的年數、月數、天數
*/
@Test
void testPeriod(){
LocalDate start = LocalDate.of(2000, 1, 1);
LocalDate end = LocalDate.of(2020, 8, 12);
LocalDate now = LocalDate.now();
Period between = Period.between(start, end);
System.out.println(between);
System.out.println(between.getYears());//間隔年份
System.out.println(between.getMonths());//間隔月份
System.out.println(between.getDays());//間隔天數
System.out.println();
}
Duration
/**
* Duration(持續時間)LocalTime、LocalDateTime、Instant
* 用於計算兩個時間物件相差的天數、小時數、分數、秒數、納秒數;支援LocalTime、LocalDateTime、Instant等時間
*
*/
@Test
void testDuration(){
LocalDateTime start = LocalDateTime.of(2000, 06, 16, 8, 15, 22, 232322);
LocalDateTime end = LocalDateTime.of(2011, 9, 22, 22, 17, 22, 64454);
Duration between = Duration.between(start, end);
System.out.println(between);
System.out.println(between.toDays());//天數
System.out.println(between.toHours());//小時
System.out.println(between.toMinutes());//分鐘
System.out.println(between.getSeconds());
System.out.println(between.toMillis());//毫秒
System.out.println(between.toNanos());//納秒
System.out.println(between.getNano());
}
Arrays(陣列)
int[] arr={2,31,5,88,44,22,66,3};
arr.toString()//返回陣列的內容
int[] ints = Arrays.copyOfRange(arr, 0, arr.length);//複製arr陣列中內容到ints中
int[] ints1 = Arrays.copyOf(arr, 10);//將陣列arr中內容複製到ints1中並指定長度
Arrays.setAll(ints1, new IntUnaryOperator() {//將ints1中的數值擴大兩倍
@Override
public int applyAsInt(int operand) {.
return ints1[operand]*2;
}
});
Arrays.sort(arr);//排序,升序
Arrays.setAll(ints1, operand->ints1[operand]*3);//lambd
Lambda表示式
Lambda表示式
注意:Lambda表示式並不是說能簡化所有的匿名內部類的方法,只能簡化函式式介面的匿名內部類。有且僅有一個抽相關方法的介面成為為函式式介面,
注意:大部分函式式介面,上面會有一個@FunctionalInterface的註解,有該註解的介面就必定是函式式介面
引數型別可以不寫,
如果只有一個引數,引數型別可以省略,同時()也可以省略
如果Lambda表示式中的方法體程式碼只有一行程式碼,可以省略大括號不寫,同時要省略分號!此時,如果這行程式碼是return語句,也必須去掉return不寫
interface Animal{
public void run();
}
@Test
void test1(){
Animal animal = new Animal() {
@Override
public void run() {
System.out.println("我是Animal");
}
};
animal.run();
Animal a =( () -> System.out.println("我是Animal"));//Lambda表示式對上述簡寫的
a.run();
}
interface TestLa{
public int test(int a,int b);
}
@Test
void test2(){
int a=39,b=33;
TestLa testLa = new TestLa() {//匿名內部類
@Override
public int test(int a, int b) {
return a + b;
}
};
System.out.println(testLa.test(a,b));
TestLa testLa1= (d,f)->d+f;//lambda表示式
System.out.println(testLa.test(33, 22));
}
方法引用
靜態方法引用
類名::靜態方法
使用場景
如果某個Lambda表示式裡只呼叫一個靜態方法,並且前後引數的形式一致,就可以使用靜態方法引用!
class CompareByData{
public static int compareByAge(People o1,People o2){
return o2.getAge()-o1.getAge();
}
}
@Test
void test3(){
People[] p=new People[4];
p[0] = new People("a", "a", "a", 131);
p[1] = new People("b", "a", "a", 14);
p[2] = new People("c", "a", "a", 1153);
p[3] = new People("d", "a", "a", 1213);
//根據年齡進行升序排序
Arrays.sort(p,(o1,o2)->o1.getAge()-o2.getAge());
// Arrays.sort(p, Comparator.comparingInt(People::getAge));//簡寫
System.out.println(Arrays.toString(p));
Arrays.sort(p,CompareByData::compareByAge);//靜態方法引用
System.out.println(Arrays.toString(p));
}
例項方法引用
物件名::例項方法
使用場景
如果某個Lambda表示式裡只有呼叫一個例項方法,並且前後引數的形式一致,就可以使用例項方法引用。
class CompareByData{
public static int compareByAge(People o1,People o2){
return o2.getAge()-o1.getAge();
}
public int compareByAgeDesc(People o1,People o2){
return o1.getAge()-o2.getAge();
}
}
@Test
void test3(){
People[] p=new People[4];
p[0] = new People("a", "a", "a", 131);
p[1] = new People("b", "a", "a", 14);
p[2] = new People("c", "a", "a", 1153);
p[3] = new People("d", "a", "a", 1213);
//根據年齡進行升序排序
Arrays.sort(p,(o1,o2)->o1.getAge()-o2.getAge());
// Arrays.sort(p, Comparator.comparingInt(People::getAge));//簡寫
System.out.println(Arrays.toString(p));
Arrays.sort(p,CompareByData::compareByAge);//靜態方法引用
System.out.println(Arrays.toString(p));
CompareByData compareByData = new CompareByData();
//升序
Arrays.sort(p,compareByData::compareByAgeDesc);//例項方法引用
System.out.println(Arrays.toString(p));
}
特定型別方法引用
型別::方法
使用場景
如果某個Lambda表示式裡只是呼叫一個例項方法,並且前面引數列表中的第一個引數是作為方法的主調,後面所有引數都是作為該例項方法的入參的,則此時就可以使用特定型別的方法引用。
@Test
void test4(){
String[] names = {"Alice", "bob", "carlie", "bovid", "Eve", "arank", "Grace", "Henry"};
// 排序(預設按照首字元編號進行升序排序)
Arrays.sort(names);
System.out.println(Arrays.toString(names));//[Alice, Eve, Grace, Henry, arank, bob, bovid, carlie]
System.out.println();
// 忽略大小寫
/* Arrays.sort(names, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareToIgnoreCase(o2);//忽略大小寫
}
});
Arrays.sort(names,(o1,o2)->o1.compareToIgnoreCase(o2));//簡寫*/
Arrays.sort(names,String::compareToIgnoreCase);//特定型別方法引用
System.out.println(Arrays.toString(names));
}
構造器引用
類名::new
使用場景
如果某個Lambda表示式裡只是在建立物件,並且前後引數情況一致,就可以使用構造器引用。
import org.junit.jupiter.api.Test;
public class TestCase {
@Test
void test1(){
Create create = new Create() {//一般引用方式
@Override
public People testPeople(String name, int age) {
return new People(name, age);
}
};
System.out.println(create.testPeople("a",22).toString());
Create create2 =People::new;//構造器引用
System.out.println(create.testPeople("b",33).toString());
}
}
interface Create{
People testPeople(String name,int age);
}
class People{
private String name;
private int age;
public People() {
}
public People(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
stream流
鏈式程式設計
stream()://建立流 map集合先轉換為單列集合再建立流
Stream.of(arr):Stream<T> of(T t)//陣列建立流的方法
Arrays.stream(arr)://陣列建立流的方法
distinct()://避免重複
filter(Predicate<? super T> predicate)://過濾器
map(Function<T, R> mapper)`: 該方法將流中的每個元素透過給定的函式進行對映,生成一個新的流。
forEach(Consumer<? super T> action)://迴圈遍歷-終結操作
詳細
filter(Predicate<T> predicate)
: 該方法用於過濾流中的元素,只保留滿足給定條件的元素。map(Function<T, R> mapper)
: 該方法將流中的每個元素透過給定的函式進行對映,生成一個新的流。flatMap(Function<T, Stream<R>> mapper)
: 該方法將流中的每個元素透過給定的函式進行對映,並將結果流扁平化為一個新的流。distinct()
: 該方法用於去除流中的重複元素,保留唯一的元素。sorted()
和sorted(Comparator<T> comparator)
:sorted()
方法用於對流中的元素進行自然排序,要求元素實現Comparable
介面;sorted(Comparator<T> comparator)
則用於根據給定的比較器對流中的元素進行排序。limit(long maxSize)
: 該方法用於截斷流,保留前面指定數量的元素。skip(long n)
: 該方法用於跳過流中的前 n 個元素,返回一個新的流。forEach(Consumer<T> action)
: 該方法對流中的每個元素執行給定的操作。collect(Collector<T, A, R> collector)
: 該方法將流中的元素收集到一個結果容器中,使用給定的收集器。reduce(BinaryOperator<T> accumulator)
和reduce(T identity, BinaryOperator<T> accumulator)
:reduce(BinaryOperator<T> accumulator)
用於將流中的元素逐個進行累積操作;reduce(T identity, BinaryOperator<T> accumulator)
則允許指定一個初始值。anyMatch(Predicate<T> predicate)
、allMatch(Predicate<T> predicate)
和noneMatch(Predicate<T> predicate)
: 這三個方法分別用於判斷流中是否存在任意滿足、全部滿足或沒有滿足給定條件的元素。findFirst()
和findAny()
:findFirst()
用於返回流中的第一個元素;findAny()
則返回流中的任意一個元素。count()
: 該方法用於返回流中元素的數量。
authors.stream()//匿名內部類形式
.distinct()
.filter(new Predicate<Author>() {
@Override
public boolean test(Author author) {
return author.getAge()<18;
}
})
.forEach(new Consumer<Author>() {
@Override
public void accept(Author author) {
System.out.println(author.getName());
}
});
authors.stream()//lambda簡寫形式
.distinct()
.filter(author -> author.getAge()<18)
.forEach(author -> System.out.println(author.getName()));
Map集合
/**
* map集合先轉換為單列集合再建立流
*/
private static void test03() {
HashMap<String, Integer> map = new HashMap<>();
map.put("a",15);
map.put("b",22);
map.put("c",26);
Set<Map.Entry<String, Integer>> entries = map.entrySet();//轉換為單列
Stream<Map.Entry<String, Integer>> stream = entries.stream();//建立流
stream.filter(new Predicate<Map.Entry<String, Integer>>() {
@Override
public boolean test(Map.Entry<String, Integer> stringIntegerEntry) {
return stringIntegerEntry.getValue()<23;
}
}).forEach((ss)-> System.out.println(ss));
}
中間操作
filter
/***
* filter
* 獲取年齡小於20的作家年齡和名字
*/
private static void test06() {
List<Author> authors = getAuthors();
authors.stream()
.filter(author -> author.getAge()<20)//查詢年齡小於20的
.forEach(author -> System.out.println(author.getAge()+"--"+author.getName()));
}
map
map(Function<T, R> mapper)
: 該方法將流中的每個元素透過給定的函式進行對映,生成一個新的流。
/**
* map
* 列印所有作家的姓名
*/
private static void test07() {
List<Author> authors = getAuthors();
authors.stream()
.map(author -> author.getName()+"--"+author.getAge())//轉換為字串返回
.forEach(a-> System.out.println(a));
}
distinct
distinct()
: 該方法用於去除流中的重複元素,保留唯一的元素。
/**
* distinct 去除重複元素
*
*/
private static void test08() {
List<Author> authors = getAuthors();
authors.stream()
.distinct()//去除重複元素
.forEach(author -> System.out.println(author.getName()));
}
sorted
排序
sorted()
和 sorted(Comparator<T> comparator)
: sorted()
方法用於對流中的元素進行自然排序,要求元素實現 Comparable
介面;sorted(Comparator<T> comparator)
則用於根據給定的比較器對流中的元素進行排序。
/**
* sorted 排序
* 對流中的元素按照年齡進行排序,要求不要有重複的元素
*/
private static void test09() {
List<Author> authors = getAuthors();
authors.stream()
.distinct()
.sorted((a,b)->a.getAge()-b.getAge())//排序,傳入物件a,b,然後透過物件獲取年齡,透過物件獲取年齡相減的順序進行排序,前後一致升序,不一致降序
.forEach(author -> System.out.println(author.getAge()));
}
limit
limit(long maxSize)
: 該方法用於截斷流,保留前面指定數量的元素。
/**
* limit
* 保留指定數量元素
*/
private static void test10() {
//獲取前三個姓名
List<Author> authors = getAuthors();
authors.stream()
.limit(3)//獲取前三個姓名
.forEach(author -> System.out.println(author.getName()));
}
skip
skip(long n)
: 該方法用於跳過流中的前 n 個元素,返回一個新的流。
/**
* skip 跳過幾個元素
*/
private static void test11() {
List<Author> authors = getAuthors();
// 跳過年齡最小的
authors.stream()
.sorted((a,b)->a.getAge()-b.getAge())//找出從小到大排列
.skip(1)//跳過第一個
.forEach(author -> System.out.println(author.getName()+"--"+author.getAge()));
}
flatMap
flatMap(Function<T, Stream<R>> mapper)
: 該方法將流中的每個元素透過給定的函式進行對映,並將結果流扁平化為一個新的流。
/**
* flatMap
* 可以返回多個物件
*/
private static void test12() {
//列印所有書籍的名字並去重
List<Author> authors = getAuthors();
authors.stream()
.flatMap(author -> author.getBooks().stream())
.distinct()
.forEach(a-> System.out.println(a.getName()));
}
/**
* flatMap
* 可以返回多個物件
*/
private static void test13() {
//列印現有資料的所有分類,要求去重,
List<Author> authors = getAuthors();
authors.stream()
.flatMap(author -> author.getBooks().stream())
.distinct()
.flatMap(author -> Arrays.stream(author.getCategory().split(",")))
.distinct()
.forEach(a-> System.out.println(a));
}
終結操作
forEach
forEach(Consumer<T> action)
: 該方法對流中的每個元素執行給定的操作。
/**
* forEach
* 對流中的每個元素執行給定的操作。
*/
private static void test14() {
List<Author> authors = getAuthors();
// 獲取所有作家的姓名
authors.stream().forEach(author -> System.out.println(author.getName()));
}
count
count()
: 該方法用於返回流中元素的數量。
/**
* count
* 返回元素中的個數
*/
private static void test15() {
List<Author> authors = getAuthors();
// 獲取所有作家的姓名
long count = authors.stream().count();
System.out.println(count);
}
collect
collect(Collector<T, A, R> collector)
: 該方法將流中的元素收集到一個結果容器中,使用給定的收集器。
/**
* collect
*/
private static void test17() {
//獲取所有存放所有作者名字的集合
List<Author> authors = getAuthors();
List<String> collect = authors.stream()
.map(author -> author.getName())
.collect(Collectors.toList());
System.out.println(collect);
}
/**
* collect
*/
private static void test18() {
//獲取所有存放所有作者名字的集合
List<Author> authors = getAuthors();
Set<String> collect = authors.stream()
.map(author -> author.getName())
.collect(Collectors.toSet());//轉換為set集合
System.out.println(collect);
}
/**
* collect
*/
private static void test19() {
//獲取一個map集合,map的key為作者名,value為List<Book>
List<Author> authors = getAuthors();
Map<String, List<Book>> collect = authors.stream()
.distinct()
.collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks()));//轉換為map集合
System.out.println(collect);
}
anyMatch、allMatch、noneMatch
anyMatch(Predicate<T> predicate)
、allMatch(Predicate<T> predicate)
和 noneMatch(Predicate<T> predicate)
: 這三個方法分別用於判斷流中是否存在任意滿足、全部滿足或沒有滿足給定條件的元素。
/**
*anyMatch
*/
private static void test20() {
//判斷是否有年齡小於20的作家
List<Author> authors = getAuthors();
boolean b = authors.stream().anyMatch(author -> author.getAge() < 20);
System.out.println(b);
}
/**
*allMatch
*/
private static void test21() {
//判斷是否有年齡小於20的作家
List<Author> authors = getAuthors();
boolean b = authors.stream().allMatch(author -> author.getAge() < 20);
System.out.println(b);
}
/**
*noneMatch
*/
private static void test22() {
//判斷是否有年齡小於20的作家
List<Author> authors = getAuthors();
boolean b = authors.stream().noneMatch(author -> author.getAge() < 20);
System.out.println(b);
}
findAny()
findAny()
則返回流中的任意一個元素。
/**
* findAny
*/
private static void test23() {
//獲取任意一個年齡大於20的作家,如果存在就輸出他的名字
List<Author> authors = getAuthors();
Optional<Author> any = authors.stream()
.filter(author -> author.getAge()>90)
.findAny();
any.ifPresent(author -> System.out.println(author.getName()));
}
findFirst()
findFirst()
用於返回流中的第一個元素;
/**
* findFirst
*/
private static void test24() {
//獲取任意一個年齡大於20的作家,如果存在就輸出他的名字
List<Author> authors = getAuthors();
Optional<Author> any = authors.stream()
.filter(author -> author.getAge()>20)
.findFirst();
any.ifPresent(author -> System.out.println(author.getName()));
}
reduce*
歸併
reduce(BinaryOperator<T> accumulator)
和 reduce(T identity, BinaryOperator<T> accumulator)
:
reduce(BinaryOperator<T> accumulator)
:用於將流中的元素逐個進行累積操作;
reduce(T identity, BinaryOperator<T> accumulator)
:則允許指定一個初始值。
/**
*reduce
*/
private static void test27() {
//使用reduce求所有作者中年齡的最小值
List<Author> authors = getAuthors();
Integer reduce = authors.stream()
.map(author -> author.getAge())
.reduce(Integer.MAX_VALUE, (age1, age2) -> age1 < age2?age1:age2);
System.out.println("最小值:"+reduce);
}
/**
*reduce
*/
private static void test26() {
//使用reduce求所有作者中年齡的最大值
List<Author> authors = getAuthors();
Integer reduce = authors.stream()
.map(author -> author.getAge())
.reduce(Integer.MIN_VALUE, (age1, age2) -> age1 > age2?age1:age2);
System.out.println("最大值:"+reduce);
}
/**
*reduce
*/
private static void test25() {
// 使用reduce計算所有作者年齡的和
List<Author> authors = getAuthors();
Integer reduce = authors.stream()
.map(author -> author.getAge())
.reduce(0, (sum, age) -> sum + age);
System.out.println("和:"+reduce);
}
/**
*reduce
傳入單個引數
*/
private static void test28() {
//使用reduce求所有作者中年齡的最小值,傳入一個引數計算
List<Author> authors = getAuthors();
Optional<Integer> reduce = authors.stream()
.map(author -> author.getAge())
.reduce((age1, age2) -> age1 < age2 ? age1 : age2);
reduce.ifPresent(age-> System.out.println(age));
}
注意事項:
惰性求值1(如果沒有終結操作,沒有中間操作是不會得到執行的)
流是一次性的(一旦一個流物件經過一個終結操作後。這個流就不能再被使用)
不會影響原資料(我們在流中可以多資料做很多處理。但是正常情況下是不會影響原來集合中的元素的。這往往也是我們期望的)
Optional
方法
在 JDK 8 中,java.util.Optional
是一個用於表示可能包含或不包含非空值的容器類。它主要用於避免空指標異常,可以更優雅地處理可能為空的值。以下是 Optional
類的一些常用方法:
-
Optional.of(T value)
:建立一個包含指定非空值的 Optional 物件。如果傳入的值為 null,將丟擲 NullPointerException。Optional<String> optionalString = Optional.of("Hello");
-
Optional.ofNullable(T value)
:建立一個 Optional 物件,如果傳入的值為 null,則返回一個空的 Optional 物件。String nullableValue = null; Optional<String> optionalString = Optional.ofNullable(nullableValue);
-
Optional.empty()
:建立一個空的 Optional 物件。Optional<String> emptyOptional = Optional.empty();
-
boolean isPresent()
:判斷 Optional 物件是否包含非空值。Optional<String> optionalString = Optional.of("Hello"); boolean isPresent = optionalString.isPresent(); // true
-
T get()
:獲取 Optional 物件中的值。注意,如果 Optional 物件為空,呼叫此方法會丟擲 NoSuchElementException。Optional<String> optionalString = Optional.of("Hello"); String value = optionalString.get(); // "Hello"
-
T orElse(T other)
:獲取 Optional 物件中的值,如果 Optional 為空,則返回指定的預設值。Optional<String> optionalString = Optional.ofNullable(null); String value = optionalString.orElse("Default Value"); // "Default Value"
-
T orElseGet(Supplier<? extends T> other)
:與orElse
類似,但是透過 Supplier 提供一個生成預設值的函式。Optional<String> optionalString = Optional.ofNullable(null); String value = optionalString.orElseGet(() -> "Default Value"); // "Default Value"
-
T orElseThrow(Supplier<? extends X> exceptionSupplier)
:獲取 Optional 物件中的值,如果 Optional 為空,則透過 Supplier 提供的函式丟擲一個異常。Optional<String> optionalString = Optional.ofNullable(null); String value = optionalString.orElseThrow(() -> new IllegalArgumentException("Value is not present"));
-
void ifPresent(Consumer<? super T> consumer)
:如果 Optional 物件中包含值,則執行傳入的消費者函式。Optional<String> optionalString = Optional.of("Hello"); optionalString.ifPresent(val -> System.out.println("Value: " + val)); // Output: Value: Hello
filter
方法,用於在 Optional 物件包含非空值時,根據指定條件進行過濾。如果滿足條件,返回原始 Optional 物件,否則返回一個空的 Optional 物件。filter
方法接受一個Predicate
函式式介面作為引數,該介面用於定義過濾的條件。map
方法,用於對Optional
物件中的值進行轉換。該方法接受一個Function
函式式介面作為引數,用於定義值轉換的邏輯。如果Optional
物件包含值,則map
方法將對該值應用函式,然後返回一個包含轉換後值的新Optional
物件。
public class OptionalDemo {
public static void main(String[] args) {
Author author = getAuthor();
Optional<Author> optionalAuthor = Optional.ofNullable(author);
optionalAuthor.ifPresent(author1 -> System.out.println(author1.getAge()));//解決傳參出現空值出現空指標異常的情況
}
private static Author getAuthor() {
Author author1 = new Author(2L, "張三", 30, "喜歡探索科學的人", null);
return null;//模擬返回空值
}
}
public static void main(String[] args) {/*
Author author = getAuthor();
Optional<Author> optionalAuthor = Optional.ofNullable(author);
optionalAuthor.ifPresent(author1 -> System.out.println(author1.getAge()));//解決傳參出現空值出現空指標異常的情況*/
Optional<Author> optionalAuthor = getOptionalAuthor();
optionalAuthor.ifPresent(author -> System.out.println(author.getAge()));
}
private static Optional<Author> getOptionalAuthor() {
Author author1 = new Author(2L, "張三", 30, "喜歡探索科學的人", null);
return Optional.ofNullable(author1);//直接進行封裝,封裝為Optional型別的
}