你好,我的程序员们, 最近是一所学校,我们被要求学习流API,而我爱上了它们。不幸的是,我没有足够的技巧来正确使用它们。我需要使用流来通过其各自的属性来过滤23座建筑物(视为对象)周围的谷底。让我示范一下: 这是我的建筑课:
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);
}
它返回一个异常 线程“主”中的异常java.lang.IndexOutOfBoundsException:索引0的长度为0超出范围。 看来我的 .filter()书写不正确,因此它没有传递任何元素。
有人可以告诉我如何正确过滤吗?
答案 0 :(得分:0)
首先,您将建筑物添加到静态列表中,但是您没有初始化此对象,因此所有字段均为空
playerPause(){
...
builder.setOngoing(false);
}
playerResume(){
...
builder.setOngoing(true);
}
如果您只想返回一个满足过滤条件的对象,请使用findFirst返回可选参数
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);
}
答案 1 :(得分:0)
问题在下面的行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"));
}
答案 2 :(得分:0)
您的过滤器是正确的。我瘦建筑类的构造函数。请设置过滤器的成员变量。
ngAfterViewInit
答案 3 :(得分:0)
问题在于列表为空,并且您试图访问不存在的第一个元素。您可以使用 findAny 或 findFirst 来返回 optional 以避免访问可能为空的对象,如果该对象为空,则可以设置默认值空
return Building.Buildings
.stream()
.filter(x -> x.getBuildingPosition() == pos)
.findAny().orElse(null);