如何在对象列表中的另一个参数的基础上返回一个参数



我有以下InventoryItem类:

@AllArgsConstructor
@Getter
public class InventoryItem {
private String name;
private int amount;
// other properties, getters, etc.
}

我有一个Inventory对象,它包含InventoryItems的List

我想获得名称与给定名称相等的项目的数量。

我正试图将流用于此目的:

inventoryItems.stream().filter(item -> item.getName().equals(name));

但它正在退回整个项目,我只想要amount。我该怎么做?我是java新手,所以不知道。

使用JDK 14:

我使用记录而不是创建POJO实现了以下代码。

注意(作为一个建议(: 正如我在给定的代码中所看到的,您正在使用一些注释(@AllArgsConstructor @Getter,..(来自动创建构造函数、getter和setter,因此对于该锅炉板代码,记录似乎是一个很好的选择,从java 14开始就可以使用

java中的记录:从JDK14开始,我们可以用记录替换我们的数据类。记录是不可变的类,只需要字段的类型和名称。我们不需要创建构造函数、getter、setter、overridetoString((方法、overridehashcode和equals方法。(记录javadoc(

请找到以下代码:

public class Test {

public static void main(String[] args) {

String nameToFind = "item1";
int amount = 0;

record InventoryItem(String name,int amount){}

Optional<Integer> optional = List.of(new InventoryItem("item1",100),
new InventoryItem("item2",200),
new InventoryItem("item3",300))
.stream().filter(x -> x.name().equals(nameToFind)).map(InventoryItem::amount).findFirst();

if(optional.isPresent()){
amount = optional.get();
}

System.out.println(amount);
}

过滤操作是一个中间操作。我们需要一个终端操作来得到结果。以下是获得金额的几种方法

import java.util.Arrays;
import java.util.List;
class InventoryItem {
String name;
float amount;
public InventoryItem(String name, float amount) {
this.name = name;
this.amount = amount;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getAmount() {
return amount;
}
public void setAmount(float amount) {
this.amount = amount;
}
}
public class ItemAmount {
public static void main(String[] args) {
List<InventoryItem> inventoryItems = Arrays.asList(new InventoryItem("A", 100f), new InventoryItem("B", 50f));
//method-1
float amount = inventoryItems.stream().filter(item -> item.getName().equals("B")).findFirst().get().getAmount();
System.out.println("Amount of B item is: " + amount);
//method-2
List<InventoryItem> matchList = inventoryItems.stream().filter(item -> item.getName().equals("B")).collect(Collectors.toList());
matchList.forEach(i -> System.out.println("Item: " + i.getName() + ", Amount: " + i.getAmount()));
}
}

使用map((函数,将其附加在过滤器之后。

Optional<int> result = inventoryItems.stream().filter(item -> item.getName().equals(name)).map(item -> item.getAmount()).findFirst();

存在以下问题:

  • 您的流缺少获取流执行结果所需的终端操作

  • InventoryItemamount,需要应用map()操作。

这就是您可以生成与具有给定名称的项目相对应的金额列表的方法:

public List<Integer> getAmountsByName(List<InventoryItem> inventoryItems,
String name) {
return inventoryItems.stream()
.filter(item -> item.getName().equals(name))
.map(InventoryItem::getAmount)
.toList(); // for Java 16+ or collect(Collectors.toList()) for earlier versions
}

如果项目名称应该是唯一的,那么您可以将findFirst()应用为终端操作,该操作将返回一个Optional作为结果(因为结果值可能不存在(。

您可以通过多种方式拨打Optional,例如,您可以使用orElse()提供默认值,或者使用orElseThrow()在未找到结果时抛出异常(有时返回Optional并在调用方法中处理它是有意义的(。

这就是它可能看起来的样子:

public int getAmountByName(List<InventoryItem> inventoryItems,
String name) {

return inventoryItems.stream()
.filter(item -> item.getName().equals(name))
.map(InventoryItem::getAmount)
.findFirst()
.orElse(-1); // in case if an item with the target name isn't present return zero
//    .orElseThrow(); // alternatively you can throw an exception depending on your needs
}

最新更新