1.檢查

我認為您可能已經厭倦了學習如何將數據流鏈接在一起。您想最終對數據做些什麼。

該類Stream具有三個標準方法,它們不構造流,而是檢查其中的數據類型。這些方法是:anyMatch()allMatch()noneMatch()

boolean anyMatch(rule)方法

此方法檢查流是否至少有一個元素滿足傳遞給該方法的規則。如果存在這樣的元素,則該方法返回true,否則返回false

例子

代碼 筆記
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
boolean result = stream.anyMatch(x -> x > 0);

true
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.anyMatch(x -> x > 0);

true
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.filter(x -> x < 0).anyMatch(x -> x > 0);

false

在最後一個示例中,我們首先只保留小於零的元素,然後檢查結果以查看是否有任何過濾元素大於零。當然,這樣的元素已經不存在了。

布爾 allMatch(rule) 方法

此方法檢查流中的所有元素是否都匹配規則(也稱為謂詞)。規則作為參數傳遞給方法:

代碼 筆記
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
boolean result = stream.allMatch(x -> x > 0);
true
(所有大於零的元素)
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.allMatch(x -> x > 0);
false
(是否有小於或等於零的元素?)
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.filter(x -> x < 0).allMatch(x -> x < 0);
true
(我們保留了小於零的元素)

在最後一個例子中,我們首先只允許小於零的元素通過過濾器,然後我們檢查是否所有保留的元素都小於零。檢查產生了積極的結果。

boolean noneMatch(rule) 方法

noneMatch()方法檢查流是否沒有與傳遞的規則匹配的元素。這就像方法的反面anyMatch()

代碼 筆記
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
boolean result = stream.noneMatch(x -> x > 0);

false
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.noneMatch(x -> x > 0);

false
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.filter(x -> x < 0).noneMatch(x -> x > 0);

true


2.實用類:Optionalclass

有時程序員使用null引用是很不方便的。例如,假設您正在比較兩個字符串。如果兩個變量都不是null,那麼您只需調用s1.equals(s2),一切都會正常進行。但如果s1可能null,那麼您必須編寫處理這種情況的代碼以避免NullPointerException.

這就是程序員想出Optional<T>實用程序類的原因。它的代碼大概是這樣的:

代碼 筆記
class Optional<Type>
{
   private final Type value;
   private Optional() { this.value = null;}
   private Optional(value) { this.value = value;}
   public static <Type> Optional<Type> of(Type value)
   {
      return new Optional<Type>(value);
   }

   public boolean isPresent()
   {
      return value != null;
   }

   public boolean isEmpty()
   {
      return value == null;
   }

   public Type get()
   {
      if (value == null)
      {
         throw new NoSuchElementException();
      }
      return value;
   }

   public Type orElse(Type other)
   {
      return value != null ? value : other;
   }

   public Type orElseThrow()
   {
      if (value == null)
      {
         throw new NoSuchElementException();
      }
      return value;
   }
}










檢查值是否不是null



檢查值是否是null




返回存儲的值。如果值為 null,則拋出異常。







返回存儲的非空值。或者,如果存儲的值為null,則返回作為方法參數傳入的值



返回存儲的非空值,或者如果值為空則拋出異常。

這個類的目的只是為了存儲一個 T 對象(對類型為 T 的對象的引用)。對象內部的對象引用Optional<T>可以是null.

這個類允許程序員編寫稍微漂亮的代碼。讓我們比較一下:

使用可選 不使用可選
public void printString(String s)
{
   Optional<String> str = Optional.ofNullable(s);
   System.out.println(str.orElse(""));
}
public void printString(String s)
{
   String str = s != null ? s : "";
   System.out.println(str)
}

始終可以使用該方法將一個Optional對象與另一個對象進行比較,即使它們存儲引用。Optionalequalsnull

簡單地說,該類允許您在對象存儲值的情況下Optional編寫“漂亮”的檢查和“漂亮”的操作。nullOptionalnull



3.尋找元素

讓我們回到課堂上Stream。該類Stream還有 4 個方法可以讓您在流中搜索元素。這些方法是findFirst()findAny()min()max()

Optional<T> findFirst()方法

findFirst()方法只返回流中的第一個元素。這就是它所做的一切。

這裡需要注意的更有趣的事情是該方法不返回對象T,而是一個Optional<T>包裝器對象。這確保該方法null在找不到對像後永遠不會返回。

例子:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String str = list.stream().findFirst().get(); // Hello

為了更清楚地說明,讓我們將最後一行分成幾行:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");

Stream<String> stream = list.stream();
Optional<String> result = stream.findFirst();
String str = result.get(); // Hello

最後一個get()方法只是檢索存儲在對像中的值Optional

Optional<T> findAny()方法

findAny()方法返回流中的任何元素並在那裡結束。此方法類似於findFirst(),但它非常適用於並行操作中使用的流。

並行處理流時,可能在流的某個部分已經找到了一個元素,但尚不清楚它是否是第一個。

如果許多元素都匹配了所有過濾器,並且程序員準確地獲取其中的第一個元素很重要,那麼findFirst()應該調用該方法。如果程序員知道實際上 0 或 1 個元素將匹配所有過濾器,那麼只需調用就足夠了findAny()——這樣會更快。

Optional<T> min(Comparator<T>)方法

min()方法使用一個comparator對象來比較流中的所有元素並返回最小的元素。定義比較器對象最方便的方法是使用 lambda 函數。

搜索最短字符串的示例:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String min = list.stream().min( (s1, s2)-> s1.length()-s2.length() ).get();

Optional<T> max(Comparator<T>)方法

max()方法使用一個comparator對象來比較流中的所有元素並返回最大元素。定義比較器對象最方便的方法是使用 lambda 函數。

搜索最長字符串的示例:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");
String max = list.stream().max( (s1, s2)-> s1.length()-s2.length() ).get();