简体   繁体   English

如何使用流过滤对象的属性?

[英]How to filter objects using streams by their attributes?

Hello there my fellow programmers, recently is school we were asked to learn streams API, and i fell in love with them.大家好,我的程序员们,最近学校要求我们学习流 API,我爱上了他们。 Unfortunately I'm not skilled enough for the proper usage of them.不幸的是,我不够熟练,无法正确使用它们。 I need to use streams to filter trough around 23 Buildings (treated as Objects) by their respective attributes.我需要使用流来过滤 23 个建筑物(被视为对象)周围的槽,它们各自的属性。 Let me demonstrate: Here is my Building class:让我演示一下:这是我的 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);
    }
}

And here is an example of my Building object这是我的建筑对象的一个​​例子

Building buld1 = new Building(1, 50, 6, "gray", 0);

Now here comes the fun, because when i tried to filter it trough this stream code:现在有趣的是,因为当我尝试通过此流代码对其进行过滤时:

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);
    }

it returned an exception Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0 .在线程“main” java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0 中返回异常Exception It seems like my .filter() is incorrectly written, so it doesn't pass any elements.似乎我的.filter() 写错了,所以它没有传递任何元素。

Can somebody show me how to filter it properly please?有人可以告诉我如何正确过滤它吗?

First you add the Building to your static list but you're not initializing this object, the fields are all empty首先,您将 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);
}

If you want to return only one object satisfying your filter use findFirst that return an Optional如果您只想返回一个满足过滤器的对象,请使用返回 Optional 的 findFirst

public static Building getBuildingByPosition(int pos) {
    Optional<Building> building = Building.Buildings
    .stream()
    .filter(x -> x.getBuildingPosition() == pos)
    .findFirst();
    return building.orElse(null);
}

Problem is in the following line return all.get(0);问题出在以下行return all.get(0);

You try to access element with index 0 but list is empty because none of the objects match filter criteria.您尝试访问索引为 0 的元素,但列表为空,因为没有任何对象符合过滤条件。

If there should either be 0 or 1 objects with at given position then you could use write something like this:如果在给定位置应该有 0 个或 1 个对象,那么您可以使用这样的写法:

public static Optional<Building> getBuildingByPosition(int pos) {
    Optional<Building> buildingAtPos= Building.Buildings
    .stream()
    .filter(x -> x.getBuildingPosition() == pos) 
    .findFirst();
    return buildingAtPos;
}

Note that now we wrap Building inside Optional , this is commonly used in situations where there might or might not be value present.请注意,现在我们将 Building 包装在Optional ,这通常用于可能存在或不存在值的情况。

If you always want to return Building or null if there isn't any building you could write it like this, but first solution is suggested way to do it:如果你总是想返回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);
}

Another option you could use if you want to enforce presence of that building:如果您想强制该建筑物的存在,您可以使用的另一个选项:

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"));
}

Your filter are correct.你的过滤器是正确的。 I thin Building class constructor.我瘦了 Building 类的构造函数。 Please set member variable for filter.请为过滤器设置成员变量。

//constructor:
public Building(int position, int cost, int rent, String color, int owner) {
    this.position = position;
    Buildings.add(this);
}

the problem was the list was empty and you were trying to access the first element which doesn't exists.问题是列表是空的,而您试图访问不存在的第一个元素。 you can use findAny or findFirst which returns optional to avoid accessing a potentially null object, which allows you to set a default value if the object is null您可以使用findAnyfindFirst返回可选以避免访问潜在的空对象,如果对象为空,则允许您设置默认值

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 java 8 流过滤列表中的对象 - filter Objects in list using java 8 streams 使用 java 8 过滤对象列表 | 过滤子对象 | 流 - Filter List of objects using java 8 | Filter on child objects | Streams 如何过滤记录Java 8个流中的null个对象 - How to filter and log null objects in Java 8 streams 使用流从内部对象分组Map属性? - Using streams to group Map attributes from inner objects? 如何使用Java 8 Streams过滤具有相同ID的对象的最大出现次数 - How to filter the Maximum number of occurrences of objects with the same id using Java 8 Streams 如何通过使用带有过滤器的另一个列表对象值来使用 java 8 流创建新列表? - How to use java 8 streams to make a new list by using another's list objects values with filter? 如何使用流根据Map字段的条件过滤一组对象? - How do I filter using streams a set of objects based on criteria for a Map field? 使用Java Streams使用过滤器将对象列表转换为字符串列表 - Convert List of Objects to List of String with filter using Java Streams 使用 Java 流过滤对象的 ArrayList 以返回字符串类型的 ArrayList - Filter an ArrayList of Objects using Java Streams to return an ArrayList of type String 使用Java Streams使用通用条件从给定列表中过滤对象 - Filter the objects from a given list with common criteria using Java Streams
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM