【问题标题】:Java lambdas and streams to map要映射的 Java lambda 和流
【发布时间】:2016-09-29 01:28:37
【问题描述】:

我有这门课:

package ProcessInvoices;

public class ProcessInvoices {

private final int partNumber;
private final String partDescription;
private int quantity;
private double price;

// constructor
public ProcessInvoices(int partNumber, String partDescription, int quantity, double price) {
    if (quantity < 0) // validate quantity
    {
        throw new IllegalArgumentException("Quantity must be >= 0");
    }

    if (price < 0.0) // validate price
    {
        throw new IllegalArgumentException(
                "Price per item must be >= 0");
    }

    this.partNumber = partNumber;
    this.partDescription = partDescription;
    this.quantity = quantity;
    this.price = price;
} // end constructor

// get part number
public int getPartNumber() {
    return partNumber; // should validate
}

// get description
public String getPartDescription() {
    return partDescription;
}

// set quantity
public void setQuantity(int quantity) {
    if (quantity < 0) // validate quantity
    {
        throw new IllegalArgumentException("Quantity must be >= 0");
    }

    this.quantity = quantity;
}

// get quantity
public int getQuantity() {
    return quantity;
}

// set price per item
public void setPrice(double price) {
    if (price < 0.0) // validate price
    {
        throw new IllegalArgumentException(
                "Price per item must be >= 0");
    }

    this.price = price;
}

// get price per item
public double getPrice() {
    return price;
}

// return String representation of ProcessInvoices object
@Override
public String toString() {
    return String.format(
            "Part #: %-2d  Description: %-15s  Quantity: %-4d  Price: $%,6.2f",
            getPartNumber(), getPartDescription(),
            getQuantity(), getPrice());
}

} 

这是驱动程序:

package ProcessInvoices;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class ProcessInvoicesDriver {

    public static void main(String[] args) {
    ProcessInvoices[] Invoice = {
        new ProcessInvoices(83, "Electric sander", 7, 57.98),
        new ProcessInvoices(24, "Power saw", 18, 99.99),
        new ProcessInvoices(7, "Sledge hammer", 11, 21.50),
        new ProcessInvoices(77, "Hammer", 76, 11.99),
        new ProcessInvoices(39, "Lawn mower", 3, 79.50),
        new ProcessInvoices(68, "Screwdriver", 106, 6.99),
        new ProcessInvoices(56, "Jig saw", 21, 11.00),
        new ProcessInvoices(3, "Wrench", 34, 7.50)};

    List<ProcessInvoices> list = Arrays.asList(Invoice);


    ////////////////////////////////////////Invoices sorted by part description
    Function<ProcessInvoices, String> desc = ProcessInvoices::getPartDescription;
    Comparator<ProcessInvoices> byPartDesc = Comparator.comparing(desc);

    System.out.printf("%nInvoices sorted by part description:%n");
    list.stream().sorted(byPartDesc).forEach(System.out::println);

    ///////////////////////////Invoices sorted by price
    Function<ProcessInvoices, Double> price = ProcessInvoices::getPrice;
    Comparator<ProcessInvoices> byPrice = Comparator.comparing(price);

    System.out.printf("%nInvoices sorted by price:%n");
    list.stream().sorted(byPrice).forEach(System.out::println);
    System.out.printf("\n");

    ///////////////// This Part Below is what i need help with ///// 
    Function<ProcessInvoices, Integer> quantity = ProcessInvoices::getQuantity;

    Comparator<ProcessInvoices> byquantity = Comparator.comparing(quantity);

    // display only first and last names
    System.out.printf("%nInvoices mapped to description and quantity:%n");
    list.stream()
            .sorted(byquantity)
            .map(ProcessInvoices::getPartDescription)
            .forEach(System.out::println);

}

}

在显示“这部分我需要帮助”的驱动程序上,我该怎么做:

使用 lambda 和流将每个 Invoice 映射到其 PartDescription 和 Quantity,按 Quantity 对结果进行排序,然后显示结果。

它的输出如下:

Invoices mapped to description and quantity:
Description: Lawn mower       Quantity: 3
Description: Electric sander  Quantity: 7
Description: Sledge hammer    Quantity: 11
Description: Power saw        Quantity: 18
Description: Jig saw          Quantity: 21
Description: Wrench           Quantity: 34
Description: Hammer           Quantity: 76
Description: Screwdriver      Quantity: 106

我做了很多事情,但我无法让它工作:我在上面的脚本中是我尝试过的最后一件事。

【问题讨论】:

  • 从列表“列表”中,我需要映射 getPartDescription 和 getQuantity 并按数量排序。我已经这样做了,但它只打印 PartDescription 而不是数量。

标签: java java-stream


【解决方案1】:

这读起来有点像家庭作业问题,因此请确保您在此处寻求帮助没有违反学校的荣誉守则。

就答案而言,您可以尝试以下方法:

list.stream()
    .collect(Collectors.toMap(desc,quantity,(q1,q2) -> q1 + q2)))
    .entrySet()
    .stream()
    .sorted(Map.Entry.comparingByValue())
    .forEach(e -> System.out.println(String.format("Description: %-15s  Quantity: %-4d",e.getKey(),e.getValue())));

collect 语句将流转换为描述、数量的映射,然后对生成的条目集进行排序和打印。 (q1,q2)-> q1 + q2 表达式是用于在列表包含重复描述时处理合并的逻辑。在这种情况下,我假设合并结果应该是两个量的总和。如果输入列表包含重复项是错误的,您可以只使用 Collections.toMap() 的两个参数版本,如果遇到重复键,则会引发异常。

有关 Collections.toMap(...) 的更多信息,您可以阅读 Java 8 javadocs here

【讨论】:

    【解决方案2】:

    您也可以在此处尝试类似于此示例的操作,它甚至可以使用您现在拥有的东西:

    System.out.println("Invoices sorted by part description:"); 
    
    Arrays.stream(invoices)          
    .sorted(Comparator.comparing(Invoice::getPartDescription))          
    .forEach(System.out::println); 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-10
      • 2023-03-19
      • 2017-09-22
      • 2022-11-01
      • 2015-07-05
      • 1970-01-01
      • 2019-04-29
      相关资源
      最近更新 更多