【问题标题】:Mapping Object to Multiple Attributes (Java)将对象映射到多个属性 (Java)
【发布时间】:2020-06-27 06:31:48
【问题描述】:

在我的 java 类中学习 lambda 和流,并试图弄清楚这一特定部分。

这是我们的任务: 使用提供的类 Invoice 创建一个 Invoice 对象数组。班级发票 包括四个实例变量; partNumber(字符串类型),partDescription(字符串类型), 正在购买的商品的数量(类型 int0 和 pricePerItem(类型为 double)。执行 对 Invoice 对象数组进行以下查询并显示结果:

一个。使用流按 partDescription 对 Invoice 对象进行排序,然后显示 结果。

b.使用流按 pricePerItem 对 Invoice 对象进行排序,然后显示结果。

c。使用流将每个 Invoice 映射到它的 partDescription 和数量,对 按数量计算结果,然后显示结果

d。使用流将每个 Invoice 映射到它的 partDescription 和 发票(即数量 * pricePerItem)。按发票值排序结果。

e。修改部分 (d) 以选择 $200.00 到 $500.00 范围内的 Invoice 值。

f。查找其中 partDescription 包含单词“saw”的任何一张 Invoice。

我在哪里: 所以我有 a) 和 b) 但我对 c) 部分有点困惑。我没有在网上或我的书中找到任何建议您可以将一个对象映射到它自己的多个属性的内容。我见过这个项目的一个例子,其中有人创建了一个单独的函数,他们创建了一个由两个元素组合而成的字符串,但我认为我的教授不会为此给予分数,因为他说没有修改他的 Invoice 类。我想知道他是否希望我们使用 lambda 来修改 Invoice 的 toString 方法,但这似乎不太正确,因为从技术上讲,我们不会映射两个属性的对象,只是映射到一个并更改它输出。在下面找到他的代码(无法修改),以及我目前拥有的代码。

教授代码(不可修改):

public class Invoice {
   private final int partNumber; 
   private final String partDescription;
   private int quantity;
   private double price;

   // constructor
   public Invoice(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;
   }

   // 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 Invoice object
   @Override
   public String toString() {
      return String.format(
         "Part #: %-2d  Description: %-15s  Quantity: %-4d  Price: $%,6.2f", 
         getPartNumber(), getPartDescription(), 
         getQuantity(), getPrice());
   } 
}

**到目前为止,这是我的代码:**

// import statements
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class InvoiceDriver {

    //***************************************************************
    //  Method:       developerInfo
    //  Description:  The developer information method of the program
    //  Parameters:   none
    //  Returns:      n/a
    //**************************************************************
    public static void developerInfo() {
        System.out.println("");
        System.out.println("*************************************************");
        System.out.println ("Name:    Allison Crenshaw");
        System.out.println ("Course:  ITSE 2317 Intermediate Java Programming");
        System.out.println ("Program: Five");
        System.out.println("*************************************************");
    } // End of developerInfo

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

        // display developer info
        developerInfo();

        // welcome message
        System.out.println("Welcome to this Invoice Program.");
        System.out.println("This program receives invoice information " +
                "and displays");
        System.out.println("the info based on various sorts using lambdas " +
                "and streams.");
        System.out.println();

        // get list view of Invoices and use to stream and print
        List<Invoice> list = Arrays.asList(invoices);

        // use a st

        // a) use streams to sort the invoices by descriptions, then display
        System.out.println("Invoices sorted by description: ");
        Arrays.stream(invoices)
                .sorted(Comparator.comparing(Invoice::getPartDescription))
                .forEach(System.out::println);
        System.out.println();

        // b) use streams to sort the invoices by price, then display
        System.out.println("Invoices sorted by price: ");
        Arrays.stream(invoices)
                .sorted(Comparator.comparing(Invoice::getPrice))
                .forEach(System.out::println);
        System.out.println();

        // c) use streams to map each invoice to its description and quantity,
        //    sort the results by quantity, then display the results
        System.out.println("Invoices mapped to description and quantity " +
                "and sorted by quantity: ");
        list.stream()
                .map(Invoice::getPartDescription)
                .forEach(System.out::println);

        // d) use streams to map each invoice to its description and the
        //    value of the invoice (quantity * price) then order by value

        // e) modify part d) to select the invoice values in range $200-$500

        // f) find any one invoice in which description contains the word "saw"


    } // main

} // end InvoiceDriver

**下面是 c) 部分的输出:**

映射到描述和数量的发票:

描述:割草机数量:3

描述:电动砂光机数量:7

描述:大锤数量:11

描述:电锯数量:18

描述:曲线锯数量:21

描述:扳手数量:34

描述:锤子数量:76

描述:螺丝刀数量:106

【问题讨论】:

  • 顺便说一句,你在用哪本书?
  • @MasterJoe2 我们在这门课上使用的书是 Java: How to Program, Early Objects – 第 11 版,Paul Deitel,Harvey Deitel – Pearson,2017,(ISBN – 9780134751856),但是,它对于这个特定的编程任务,没有最好的例子。
  • @beebus - 我最近也读了那本书,我同意。我认为大多数教科书没有足够的练习来彻底测试自己并很好地记住这些概念。我怀疑人们是否会在仅解决 10-15 个练习后记住任何东西。除了论坛上的问题,我建议从多本教科书中挑选问题并全部完成。祝你好运。

标签: java lambda maps java-stream mapping


【解决方案1】:

按照您映射Stream 的方式,您将只能同时访问partDescription 而不能同时访问quantity

.map(Invoice::getPartDescription) // changed to Stream<String> from Stream<Invoice>

使用流将每个 Invoice 映射到其 partDescription 和数量, 按数量对结果进行排序,然后显示结果

考虑同时保留这两个属性的元组,Map 可能有助于收集信息以进行进一步处理(排序)。这看起来像:

list.stream()
        .collect(Collectors.toMap(Invoice::getPartDescription,
                Invoice::getQuantity)) // map description to its quantity
        .entrySet().stream()
        .sorted(Map.Entry.comparingByValue()) // sort by quantity (values of map)
        .forEach(e -> System.out.println("Description: " + e.getKey() + " Quantity: " + e.getValue()));
  • 您可以对“d”部分使用类似的方法来更改属性。
  • 对于“e”部分,您需要使用.filter 选择性地处理元素。
  • 一旦您知道如何filter,您需要findAny 使用“f”部分,同时根据描述周围的给定条件进行过滤。

【讨论】:

  • 有没有办法在不映射到列表的情况下执行第 d 部分?所以使用流将每个 Invoice 映射到它的 partDescription 和 Invoice 的值(即数量* pricePerItem)???似乎您会使用 reduce,但我无法获得正确的语法来计算该值。我试过 (Invoice::getQuantity * Invoice::getPrice) 没有成功。对它的外观有任何见解吗?
【解决方案2】:

您可以将元素映射到您想要的任何内容,例如,String

list.
    stream().
    sorted(Comparator.comparing(Invoice::getQuantity)).
    map(invoice -> 
        String.format(
            "Description: %-15s  Quantity: %-4d", 
            invoice.getPartDescription(), 
            invoice.getQuantity()
        )
    ).
    forEach(System.out::println);

【讨论】:

    【解决方案3】:

    这里是解决方案。看起来您已经很好地理解了流和 lambda。所以,我并没有在代码 cmets 中添加过多的解释。如果您需要任何解释,请告诉我。

    import java.util.Arrays;
    import java.util.Comparator;
    import java.util.List;
    import java.util.stream.Collectors;
    import java.util.stream.IntStream;
    
    public class InvoiceProcessor {
    
        //MAIN METHOD - START HERE !!!
        public static void main(String[] args) {
            List<Invoice> invoices = getInvoices();
            System.out.println("\nQuestion A:");
            partA(invoices);
            System.out.println("\nQuestion B:");
            partB(invoices);
            System.out.println("\nQuestion C:");
            partC(invoices);
            System.out.println("\nQuestion D:");
            partD(invoices);
            System.out.println("\nQuestion E:");
            partE(invoices);
            System.out.println("\nQuestion F:");
            partF(invoices);
        }
    
        //Generate some sample invoices to use in our code - using lambdas and streams!
        public static List<Invoice> getInvoices(){
            List<String> partNames = Arrays.asList("Lawn mower", "Electric sander", "Sledge hammer",
                    "Power saw", "Jig saw", "Wrench", "Hammer", "Screwdriver");
    
            List<Invoice> invoices = IntStream
                    .range(0, partNames.size())
                    //Use each number to generate Invoices,i.e. 1 number is MAP-ped to 1 invoice.
                    .mapToObj(n -> new Invoice(n, partNames.get(n), (n%3)+1, (n+1) * 50.0))
                    //Collect all the invoices in a list.
                    .collect(Collectors.toList());
    
            return invoices;
        }
    
        //a. Use streams to sort the Invoice objects by partDescription, then display the results.
        public static void partA(List<Invoice> invoices){
            invoices.stream()
                    .sorted(Comparator.comparing(Invoice::getPartDescription))
                    .forEach(System.out::println);
        }
    
        //b. Use streams to sort the Invoice objects by pricePerItem, then display the results.
        public static void partB(List<Invoice> invoices){
            invoices.stream()
                    .sorted(Comparator.comparing(Invoice::getPrice))
                    .forEach(System.out::println);
        }
    
        //c. Use streams to map each Invoice to its partDescription and quantity, sort the results by quantity,
        // then display the results.
        public static void partC(List<Invoice> invoices){
            //Do we really need to do any mapping here?
            invoices.stream()
                    .sorted(Comparator.comparing(Invoice::getQuantity))
                    .forEach(i -> System.out.println("Description: " + i.getPartDescription() + " Quantity: " + i.getQuantity())
                    );
        }
    
        //d. Use streams to map each Invoice to its partDescription and the value of the
        // Invoice (i.e., quantity * pricePerItem). Order the results by Invoice value.
        public static void partD(List<Invoice> invoices){
            //Do we really need to do any mapping here?
            invoices.stream()
                    .sorted( Comparator.comparingDouble(i -> i.getQuantity() * i.getPrice() ) )
                    .forEach(i -> System.out.println("Description: " + i.getPartDescription() + " Invoice value: " + i.getQuantity() * i.getPrice())
                    );
        }
    
        //e. Modify Part (d) to select the Invoice values in the range $200.00 to $500.00.
        public static void partE(List<Invoice> invoices){
            invoices.stream()
                    .filter(i -> 200.0 <= i.getQuantity() * i.getPrice() && i.getQuantity() * i.getPrice() <= 500.0)
                    .forEach(i -> System.out.println("Description: " + i.getPartDescription() + " Invoice value: " + i.getQuantity() * i.getPrice()));
        }
    
        //f. Find any one Invoice in which the partDescription contains the word "saw".
        public static void partF(List<Invoice> invoices){
            Invoice saw = invoices.stream()
                    .filter(i -> i.getPartDescription().contains("saw"))
                    .findFirst()
                    .get();
            System.out.println(saw);
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2017-03-16
      • 1970-01-01
      • 2018-08-24
      • 2017-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多