我想優化我的代碼。我曾經使用 for 回圈和 ifs,但我知道還有比這更快的方法。我對 lambdas 和流還很陌生。為了實踐,我決定用它們替換我的舊代碼。我很好奇,下面的代碼會如何改變。
int counter = 0;
List<Integer> points = new ArrayList<>();
for (String name : names) {
for (Car car : cars) {
if (counter != 0) {
points.add(counter);
}
counter= 0;
for (Driver driver : car.getDriversWhoDrivesIt()) {
if (driver.getYearsInMotorsport() == 15) {
if (!(names.contains(driver.getName()))) {
filteredCars.remove(car);
counter= 0;
break;
}
}
if (driver.getYearsInMotorsport() == 7 ) {
counter = 7;
}
if (driver.getYearsInMotorsport() == 3) {
counter = 3;
}
}
}
}
所以這里的任務是有一個串列(名稱),其中包含用戶之前定義的驅動程式。之后,我遍歷所有駕駛該汽車的司機,如果有人恰好有 15 年的經驗并且用戶沒有選擇它(在名稱串列中),那么司機駕駛的汽車就被淘汰了(從過濾的汽車中洗掉并且沒有需要繼續使用那輛車)。
因此,例如,我有 3 輛汽車和有 exp 的司機:
- 車:劉易斯(15年),馬可(4),塞巴斯蒂安(15)
- 車:馬克斯(15),阿曼達(7)
- 車:鮑勃(15)、喬治(3)、蘭多(15)
比用戶定義的名字:Lewis、Bob、Amanda、Lando、Max
如果司機有 15 年的 exp 并且用戶沒有定義它,那么我不希望那輛車出現在我的過濾汽車中。如果定義了所有 15 年的 exp 驅動程式,我想收集其他驅動程式 exp(counter)
所以最后我想要我的filteredCar串列是這樣的: 2. car - 7 3.car - 3
解釋:第一輛車被淘汰了,因為用戶沒有定義有 15 年的 Sebastian。第二輛和第三輛升職了,因為用戶定義了所有 15 年有經驗的司機,第二輛得 7 分(因為阿曼達),第三輛得 3 分(喬治)。
我試圖用 flatMap 解決這個問題。但我被 if-s 困住了。我的問題是我需要在 lambdas 中使用 inline if 但我的 if-s 沒有 else 部分。
names.stream()
.flatMap(name -> cars.stream()
.flatMap(car -> car.getDriversWhoDrivesIt().stream()
// .flatMap(driver -> driver.getYearsInMotorsport() == 5 ? ) //?? now what?
)
);
我希望有人可以幫助我解決這個問題。
uj5u.com熱心網友回復:
我建議不要定義名稱串列,而是定義一個Set. 對于每個Car過濾器驅動程式,具有確切15年份的經驗,然后使用操作檢查它們是否都存在于用戶定義的名稱集中allMatch()。
然后Car使用收集器將流中剩余的所有物件收集到地圖中toMap():
Set<String> names = Set.of("Lewis", "Bob", "Amanda", "Lando", "Max");
List<Car> cars = List.of(
new Car("Car1", List.of(new Driver("Lewis", 15),
new Driver("Marco", 4),
new Driver("Sebastian", 15))
),
new Car("Car2", List.of(new Driver("Max", 15),
new Driver("Amanda", 7))
),
new Car("Car3", List.of(new Driver("Bob", 15),
new Driver("George", 3),
new Driver("Lando", 15))
)
);
Map<Car, Integer> pointByCar = cars.stream()
.filter(car -> car.getDrivers().stream()
.filter(driver -> driver.getYearsInMotorsport() == 15)
.map(Driver::getName)
.allMatch(names::contains)
)
.collect(Collectors.toMap(
Function.identity(),
car -> car.getDrivers().stream()
.mapToInt(Driver::getYearsInMotorsport)
.filter(i -> i == 7 || i == 3)
.sum()
));
pointByCar.forEach((car, points) -> System.out.println(car " -> " points));
輸出:
Car{name='Car2'} -> 7
Car{name='Car3'} -> 3
在線演示的鏈接
uj5u.com熱心網友回復:
我知道有比這更快的方法
只有寫得更快,有些人可能會發現它更具可讀性。
在此示例中,我將從流中洗掉具有 15 年經驗的駕駛員且未列在名稱串列中的汽車。然后我只是將結果收集到地圖中。關鍵是車。價值是司機年數的總和——擁有 15 年經驗的司機。
Map<Car, Integer> filteredCars = cars.stream()
.filter(car -> car.driversWhoDrivesIt().stream().allMatch(driver -> driver.yearsInMotorsport() != 15 || names.contains(driver.name())))
.collect(Collectors.toMap(
Function.identity(),
car -> car.driversWhoDrivesIt().stream()
.mapToInt(Driver::yearsInMotorsport)
.filter(y -> y != 15)
.sum()));
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/512366.html
