1.reduce
在Java中,可以使用Stream API的reduce方法來計算一個整數列表的乘積。reduce方法是一種累積操作,它可以將流中的元素組合起來,返回單個結果。對于計算乘積,你需要提供一個初始值(通常是1,因為乘法的單位元是1)和一個二元操作符(這里是乘法操作)。
以下是一個示例代碼,演示如何使用reduce方法來計算一個整數列表的乘積:
import java.util.Arrays;import java.util.List;import java.util.Optional;public class ProductCalculator {public static void main(String[] args) {List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);// 使用reduce方法計算乘積Optional<Integer> product = numbers.stream().reduce(1, (a, b) -> a * b);// 由于reduce返回的是Optional,需要處理可能的空值if (product.isPresent()) {System.out.println("The product of the list is: " + product.get());} else {System.out.println("The list is empty or some error occurred.");}}
}
``
在這個例子中:numbers.stream() 創建一個整數列表的流。
.reduce(1, (a, b) -> a * b) 從1開始,將流中的每個元素依次乘以當前的結果。這里1是初始值,(a, b) -> a * b是累積操作(即將當前結果a與下一個元素b相乘)。
reduce方法返回一個Optional<Integer>,因為流操作可能會返回一個空的結果(例如,當流為空時)。
使用if (product.isPresent())來檢查乘積是否存在,如果存在則打印乘積,否則打印錯誤信息。
此外,如果確定列表不會為空,你也可以直接使用orElse方法來提供一個默認值,從而簡化代碼:```javapublic class ProductCalculator {public static void main(String[] args) {List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);// 使用reduce方法計算乘積,并提供默認值int product = numbers.stream().reduce(1, (a, b) -> a * b).orElse(1); // 如果列表為空,返回1作為默認值System.out.println("The product of the list is: " + product);}}
在這個改進的版本中,如果流為空,orElse(1)會確保返回一個默認值1,而不是處理Optional對象。
collect和collector.xx
List<Student> students = Arrays.asList(new Student("Alice", 20),new Student("Bob", 22),new Student("Charlie", 20),new Student("David", 22));//Arrays,collections//按學生的年齡分組。////打印每個年齡對應的學生姓名列表。students.stream().collect(Collectors.groupingBy(Student::getAge))//這里得到一個Map<Integer,list<String>>,然后利用foreach遍歷Map集合.forEach((age, studentsInAge) -> {System.out.println("Age: " + age);studentsInAge.forEach(student -> System.out.println(" Name: " + student.getName()));});```### 附:Map集合使用foreach遍歷```javaMap<String, Integer> map = new HashMap<>();
map.put("Apple", 1);
map.put("Banana", 2);
map.put("Cherry", 3);map.forEach((key, value) -> {System.out.println("Key: " + key + ", Value: " + value);
});
在 Java 的 Stream
API 中,map
方法用于將流中的每個元素轉換為另一種形式。你可以使用 map
方法來對流中的每個元素進行某種操作,并返回一個新的流,其中包含轉換后的元素。
stream流的map方法基本用法
map
方法的簽名如下:
<R> Stream<R> map(Function<? super T, ? extends R> mapper)
T
是流中當前元素的類型。R
是轉換后的新元素的類型。Function<T, R>
是一個函數接口,它接受一個T
類型的參數并返回一個R
類型的結果。
示例
- 基本示例:將整數列表中的每個元素平方
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> squares = numbers.stream().map(n -> n * n) // 將每個元素平方.collect(Collectors.toList());
System.out.println(squares); // 輸出 [1, 4, 9, 16, 25]
- 將字符串列表中的每個元素轉換為大寫
List<String> words = Arrays.asList("apple", "banana", "grape", "kiwi", "orange");
List<String> upperCaseWords = words.stream().map(String::toUpperCase) // 將每個字符串轉換為大寫.collect(Collectors.toList());
System.out.println(upperCaseWords); // 輸出 [APPLE, BANANA, GRAPE, KIWI, ORANGE]
- 將對象列表中的某個屬性提取出來
List<Student> students = Arrays.asList(new Student("Alice", 20),new Student("Bob", 22),new Student("Charlie", 20),new Student("David", 22)
);List<String> names = students.stream().map(Student::getName) // 提取每個學生的姓名.collect(Collectors.toList());
System.out.println(names); // 輸出 [Alice, Bob, Charlie, David]
- 將對象列表中的某個屬性轉換為另一個對象
List<Person> people = Arrays.asList(new Person("Alice", 20),new Person("Bob", 17),new Person("Charlie", 25)
);List<String> upperCaseNames = people.stream().filter(person -> person.getAge() > 18) // 過濾年齡大于18的人.map(person -> person.getName().toUpperCase()) // 將名字轉換為大寫.collect(Collectors.toList());
System.out.println(upperCaseNames); // 輸出 [ALICE, CHARLIE]
完整代碼示例
以下是你的代碼中未完成的部分,以及如何使用 map
方法來完成它:
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;public class Test01 {public static void main(String[] args) {// 其他代碼...System.out.println("-----------------------------------------");// 過濾出所有年齡大于18歲的人。// 將他們的名字轉換為大寫。// 收集到一個新的列表中并打印。List<Person> people = Arrays.asList(new Person("Alice", 20),new Person("Bob", 17),new Person("Charlie", 25));List<String> upperCaseNames = people.stream().filter(person -> person.getAge() > 18) // 過濾年齡大于18的人.map(person -> person.getName().toUpperCase()) // 將名字轉換為大寫.collect(Collectors.toList()); // 收集到新的列表System.out.println(upperCaseNames); // 輸出 [ALICE, CHARLIE]}
}class Person {String name;int age;public Person() {}public Person(String name, int age) {this.name = name;this.age = age;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
解釋
filter(person -> person.getAge() > 18)
:過濾出年齡大于18歲的Person
對象。map(person -> person.getName().toUpperCase())
:將每個Person
對象的名字轉換為大寫。collect(Collectors.toList())
:將轉換后的名字收集到一個新的List
中。
## collector
Collectors
是 Java 8 中 Stream
API 提供的一個強大工具,用于將流中的元素收集到集合或其他數據結構中。以下是一些常見的 Collectors
用法示例:
1. 收集到 List
將流中的元素收集到一個 List
中。
List<String> words = Arrays.asList("apple", "banana", "grape", "kiwi", "orange");
List<String> longWords = words.stream().filter(word -> word.length() > 5).collect(Collectors.toList());
System.out.println(longWords); // 輸出 [banana, orange]
2. 收集到 Set
將流中的元素收集到一個 Set
中,自動去重。
List<String> words = Arrays.asList("apple", "banana", "apple", "kiwi", "banana");
Set<String> uniqueWords = words.stream().collect(Collectors.toSet());
System.out.println(uniqueWords); // 輸出 [banana, apple, kiwi]
3. 收集到 Map
將流中的元素收集到一個 Map
中,鍵為元素本身,值為元素的長度。
List<String> words = Arrays.asList("apple", "banana", "grape", "kiwi", "orange");
Map<String, Integer> wordLengthMap = words.stream().collect(Collectors.toMap(word -> word, // Key: 單詞本身String::length // Value: 單詞長度));
System.out.println(wordLengthMap); // 輸出 {apple=5, banana=6, grape=5, kiwi=4, orange=6}
4. 分組(Grouping By)
將流中的元素按某個屬性分組。
List<Student> students = Arrays.asList(new Student("Alice", 20),new Student("Bob", 22),new Student("Charlie", 20),new Student("David", 22)
);Map<Integer, List<Student>> studentsByAge = students.stream().collect(Collectors.groupingBy(Student::getAge));studentsByAge.forEach((age, studentList) -> {System.out.println("Age: " + age);studentList.forEach(student -> System.out.println(" Name: " + student.getName()));
});
5. 分區(Partitioning By)
將流中的元素按某個條件分為兩個分區(true
和 false
)。
List<String> words = Arrays.asList("apple", "banana", "grape", "kiwi", "orange");
Map<Boolean, List<String>> partitionedWords = words.stream().collect(Collectors.partitioningBy(word -> word.length() > 5));System.out.println("Long words: " + partitionedWords.get(true)); // 輸出 [banana, orange]
System.out.println("Short words: " + partitionedWords.get(false)); // 輸出 [apple, grape, kiwi]
6. 連接字符串(Joining)
將流中的字符串元素連接成一個字符串。
List<String> words = Arrays.asList("apple", "banana", "grape", "kiwi", "orange");
String joinedWords = words.stream().collect(Collectors.joining(", "));
System.out.println(joinedWords); // 輸出 apple, banana, grape, kiwi, orange
7. 統計匯總(Summarizing)
對流中的元素進行統計匯總,如求和、平均值、最大值、最小值等。
List<Integer> numbers = Arrays.asList(3, 12, 8, 15, 20, 7, 10);
IntSummaryStatistics stats = numbers.stream().collect(Collectors.summarizingInt(Integer::intValue));System.out.println("Sum: " + stats.getSum()); // 輸出 75
System.out.println("Average: " + stats.getAverage()); // 輸出 10.714285714285714
System.out.println("Max: " + stats.getMax()); // 輸出 20
System.out.println("Min: " + stats.getMin()); // 輸出 3
8. 自定義收集器
通過 Collector.of
自定義收集器。
List<String> words = Arrays.asList("apple", "banana", "grape", "kiwi", "orange");
String concatenated = words.stream().collect(Collector.of(StringBuilder::new, // Supplier: 創建一個新的 StringBuilderStringBuilder::append, // Accumulator: 將每個元素添加到 StringBuilderStringBuilder::append, // Combiner: 合并兩個 StringBuilder(用于并行流)StringBuilder::toString // Finisher: 將 StringBuilder 轉換為字符串));
System.out.println(concatenated); // 輸出 applebananagrapekiwiorange