[英]How to filter objects using streams by their attributes?
大家好,我的程序員們,最近學校要求我們學習流 API,我愛上了他們。 不幸的是,我不夠熟練,無法正確使用它們。 我需要使用流來過濾 23 個建築物(被視為對象)周圍的槽,它們各自的屬性。 讓我演示一下:這是我的 Building 課程:
class Building {
String color;
int position;
int cost;
int rent;
int owner;
//ArrayList for storing all of the buildings
public static ArrayList<Building> Buildings = new ArrayList<>();
//getter of the position of this building
public int getBuildingPosition() {
return position;
}
//constructor:
public Building(int position, int cost, int rent, String color, int owner) {
Buildings.add(this);
}
}
這是我的建築對象的一個例子
Building buld1 = new Building(1, 50, 6, "gray", 0);
現在有趣的是,因為當我嘗試通過此流代碼對其進行過濾時:
public static Building getBuildingByPosition(int pos) {
List<Building> all = Building.Buildings
.stream()
.filter(x -> x.getBuildingPosition() == pos) // here may be the error
.collect(Collectors.toList());
return all.get(0);
}
它在線程“main” java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0 中返回異常Exception 。 似乎我的.filter() 寫錯了,所以它沒有傳遞任何元素。
有人可以告訴我如何正確過濾它嗎?
首先,您將 Building 添加到您的靜態列表中,但您沒有初始化此對象,這些字段都是空的
public Building(int position, int cost, int rent, String color, int owner) {
this.position = position;
this.cost = cost;
this.rent = rent;
this.color = color;
this.owner = owner;
Buildings.add(this);
}
如果您只想返回一個滿足過濾器的對象,請使用返回 Optional 的 findFirst
public static Building getBuildingByPosition(int pos) {
Optional<Building> building = Building.Buildings
.stream()
.filter(x -> x.getBuildingPosition() == pos)
.findFirst();
return building.orElse(null);
}
問題出在以下行return all.get(0);
您嘗試訪問索引為 0 的元素,但列表為空,因為沒有任何對象符合過濾條件。
如果在給定位置應該有 0 個或 1 個對象,那么您可以使用這樣的寫法:
public static Optional<Building> getBuildingByPosition(int pos) {
Optional<Building> buildingAtPos= Building.Buildings
.stream()
.filter(x -> x.getBuildingPosition() == pos)
.findFirst();
return buildingAtPos;
}
請注意,現在我們將 Building 包裝在Optional
,這通常用於可能存在或不存在值的情況。
如果你總是想返回Building
或 null 如果沒有任何建築物你可以這樣寫,但第一個解決方案是建議的方法:
public static Optional<Building> getBuildingByPosition(int pos) {
Optional<Building> buildingAtPos= Building.Buildings
.stream()
.filter(x -> x.getBuildingPosition() == pos)
.findFirst();
return buildingAtPos.orElse(null);
}
如果您想強制該建築物的存在,您可以使用的另一個選項:
public static Optional<Building> getBuildingByPosition(int pos) {
Optional<Building> buildingAtPos= Building.Buildings
.stream()
.filter(x -> x.getBuildingPosition() == pos)
.findFirst();
return buildingAtPos.orElseThrow(()-> new IllegalStateException("Building at position " + pos + " must exist"));
}
你的過濾器是正確的。 我瘦了 Building 類的構造函數。 請為過濾器設置成員變量。
//constructor:
public Building(int position, int cost, int rent, String color, int owner) {
this.position = position;
Buildings.add(this);
}
問題是列表是空的,而您試圖訪問不存在的第一個元素。 您可以使用findAny或findFirst返回可選以避免訪問潛在的空對象,如果對象為空,則允許您設置默認值
return Building.Buildings
.stream()
.filter(x -> x.getBuildingPosition() == pos)
.findAny().orElse(null);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.