簡體   English   中英

如何使用流過濾對象的屬性?

[英]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);
}

問題是列表是空的,而您試圖訪問不存在的第一個元素。 您可以使用findAnyfindFirst返回可選以避免訪問潛在的空對象,如果對象為空,則允許您設置默認值

return Building.Buildings
                .stream()
                .filter(x -> x.getBuildingPosition() == pos)
                .findAny().orElse(null);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM