Java数据处理与I/O操作:流、映射迭代与对象序列化
立即解锁
发布时间: 2025-08-18 02:16:51 阅读量: 2 订阅数: 7 

### Java 数据处理与 I/O 操作:流、映射迭代与对象序列化
#### 1. Java 流的变革
在 Java 编程中,流(Streams)带来了革命性的变化。它改变了开发者对程序的思考方式,提高了开发效率,使代码更加高效。虽然传统的迭代技术(如 for 循环)仍然有效,但在 Java 8 及更高版本中,流是首选的迭代技术。
#### 2. 映射(Map)的迭代
##### 2.1 问题描述
当使用 `Map` 类(如 `HashMap` 或 `TreeMap`)时,可能需要迭代键、值或两者,并且可能需要在迭代过程中移除元素。
##### 2.2 解决方案
有多种方法可以迭代 `Map` 类,选择的方法应取决于需要访问的映射部分以及是否需要在迭代时移除元素。以下是一个 `StockPortfolio1` 类的示例,展示了不同的迭代方法:
```java
import org.java17recipes.chapter07.recipe07_07.Stock;
import org.java17recipes.chapter07.recipe07_06.StockScreener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class StockPortfolio1 implements Iterable<Stock> {
Map<String, Stock> portfolio = new HashMap<>();
public void add(Stock stock) {
portfolio.put(stock.getSymbol(), stock);
}
public void add(List<Stock> stocks) {
for (Stock s : stocks) {
portfolio.put(s.getSymbol(), s);
}
}
public void remove(String stock) {
portfolio.remove(stock);
}
public void remove(List<String> sellList) {
Iterator<String> keyIter = portfolio.keySet().iterator();
while (keyIter.hasNext()) {
if (sellList.contains(keyIter.next())) {
keyIter.remove();
}
}
}
public List<Stock> alertListLegacy() {
System.out.println("==Legacy technique for filtering and collecting==");
List<Stock> alertList = new ArrayList<>();
for (Stock stock : portfolio.values()) {
if (!StockScreener.screen(stock.getSymbol(), StockScreener.Screen.PE, 20)) {
alertList.add(stock);
}
}
return alertList;
}
public List<Stock> alertList() {
return portfolio.values().stream()
.filter(s -> !StockScreener.screen(s.getSymbol(), StockScreener.Screen.PE, 20))
.collect(Collectors.toList());
}
public void summary() {
System.out.println("==Legacy technique for traversing Map.Entry==");
for (Map.Entry<String, Stock> entry : portfolio.entrySet()) {
System.out.println("Stock = " + entry.getKey() + ", Shares = " + entry.getValue().getShares());
}
System.out.println("==Utilization of new foreach and lambda combination==");
portfolio.forEach((k, v) -> System.out.println("Stock = " + k + ", Shares = " + v.getShares()));
}
@Override
public Iterator<Stock> iterator() {
return portfolio.values().iterator();
}
public static void main(String[] args) {
StockPortfolio1 myPortfolio = new StockPortfolio1();
myPortfolio.add(new Stock("ORCL", "Oracle", 500.0));
myPortfolio.add(new Stock("AAPL", "Apple", 200.0));
myPortfolio.add(new Stock("GOOG", "Google", 100.0));
myPortfolio.add(new Stock("IBM", "IBM", 50.0));
myPortfolio.add(new Stock("MCD", "McDonalds", 300.0));
for (Stock stock : myPortfolio) {
System.out.println(stock);
}
myPortfolio.forEach((stock) -> System.out.println(stock));
List<String> sellList = new ArrayList<>();
sellList.add("IBM");
sellList.add("GOOG");
myPortfolio.remove(sellList);
System.out.println("Portfolio Summary:");
myPortfolio.summary();
System.out.println("Alerts:");
for (Stock stock : myPortfolio.alertList()) {
System.out.println("Alert: " + stock.getSymbol());
}
}
}
```
##### 2.3 工作原理
- **`summary()` 方法**:使用 `foreach` 循环迭代投资组合映射的 `Entry` 集。传统方法使用 `Map` 的 `entrySet()` 方法返回 `Map.Entry` 对象的集合,在循环中通过 `getKey()` 和 `getValue()` 方法访问键和值。新语法使用 Java 8 中 `Map` 接口添加的 `forEach()` 方法和 lambda 表达式,可在一行代码中完成相同的迭代。
- **`alertListLegacy()` 方法**:使用 `foreach` 循环迭代投资组合映射的值。`Map` 的 `values()` 方法返回映射值的集合。当只需要访问映射值且不需要移除元素时,可使用此方法。如果只需要访问映射键,可使用 `keySet()` 方法。
- **`alertList()` 方法**:使用流、过滤器和收集器的组合,以更少的代码完成相同的迭代。首先生成一个流,然后应用一个 lambda 表达式作为过滤器,最后使用收集器将过滤后的结果收集到一个列表中。
- **`remove(List<String>)` 方法**:使用 `keySet()` 迭代器遍历投资组合映射的键,根据给定的股票符号列表移除相应的元素。也可以使用 `values()` 迭代器进行相同的操作。
总结来说,如果需要在迭代映射时移除元素,应使用映射的集合迭代器并通过迭代器移除元素;如果不需要移除元素,可以使用 `foreach` 循环和上述的迭代方法。
#### 3. 并行流的执行
##### 3.1 问题描述
希望并行迭代集合,以将工作分配到多个 CPU 上。
##### 3.2 解决方案
在集合上使用流构造,并将 `parallelStream()` 作为第一个中间操作,以利用多个 CPU 进行处理。以下是一个 `StockPortfolio2` 类的示例:
```java
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stre
```
0
0
复制全文
相关推荐










