【问题标题】:Attach values to elements of a List in Java在 Java 中将值附加到 List 的元素
【发布时间】:2019-07-29 00:24:46
【问题描述】:

我有一个整数列表,我从中计算重复次数并使用地图将其打印出来。现在Items 列表中的每个整数都必须有一个特定的值才能分配给它们。

我的输出是:

2 x 3

8 x 1

最终我想要实现的是:

2 x 3 $5.50

8 x 1 $12.50

Total = $29

这意味着整数 2 和 8 各有一个值,分别为 $5.50 和 $12.50。

  1. 在 Java 中为该列表中的整数赋值的最佳方法是什么?

  2. 如何处理计算?

该程序接受烘焙食品的订单 - 总数量以及作为输入的代码。例如 14 个松饼。每个项目都有一组可用的包裹(比如 2、5、8),每个都有它的成本。我使用硬币找零算法分解了可用包装中的 14 个松饼。

例如输入 = 14 个松饼

预期输出:

14 块松饼 $54.8

1 x 8 美元 24.95 美元

3 x 2 $9.95

我已经使用硬币找零算法完成了包装分解,现在我正在寻找设置 OO 设计以实现输出的最佳方法。我非常感谢您对此提出任何建议。

这是我从列表中获取重复项的代码:

public static void packagesprint() {
        List<Integer> items = Arrays.asList(8, 2, 2, 2);

        Map<Integer, Long> result = items.stream()
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

        for (Map.Entry<Integer,Long> entry : result.entrySet())
            System.out.println(entry.getKey() + " x "+
                    + entry.getValue());    
    }

输出:

2x3

8x1

【问题讨论】:

  • 实际上,在任何逻辑情况下,整数 2 的值为 2。我认为更好的方法是创建一个 Id = 2 且值为 5.50 美元的复合对象
  • 为什么是2x3(5.50) + 8x1(12.50) = 285.5*3 + 12.5 = 29,不是吗?
  • @Alessandro:我的错。编辑错误
  • 哪里存储关联2=5.50$8=12.50$等...?
  • @Alessandro:我还没有存储在任何地方。我的问题的一部分基本上是获得有关如何处理的最佳建议。到目前为止,我已经使用硬币找零算法将一个值分解为它的面额。现在,这些面额中的每一个都需要分配一个值。您对此有何建议?

标签: java list oop arraylist collections


【解决方案1】:

这听起来像是某种购物卡。我会使用产品目录(可以存储在数据库中):

public class Catalogue {
    public Product getProductById(int id) {
        // ...
    }

    // ...
}

public class Product {
    private int id;
    private String label;
    private double price;
    // ...

    public int getId() {
        return id;
    }

    public String getLabel() {
        return label;
    }

    public double getPrice() {
        return price;
    }

    // ...
}

我会定义一个类Order,它是OrderItem 的集合。每个项目都是一个数量和一个产品。要对订单中的商品进行分组,您可以使用以商品 ID 作为键的地图:

public class OrderItem {
    private int quantity;
    private Product product;

    public OrderItem(int quantity, Product product) {
        this.quantity = quantity;
        this.product = product;
    }

    public int getQuantity() {
        return quantity;
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    public Product getProduct() {
        return product;
    }

    public double getAmount() {
        return quantity*product.getPrice();
    }
}

public class Order {
    private final Map<Integer,OrderItem> items = new HashMap<>();

    public Iterable<OrderItem> getItems() {
        return new ArrayList<>(items.values());
    }

    public void add(int quantity, Product product) {
        OrderItem item = items.get(product.getId());
        if (item != null) {
            item.setQuantity(item.getQuantity() + quantity);
        } else {
            items.put(product.getId(), new OrderItem(quantity, product));
        }
    }

    public void add(Product product) {
        add(1, product);
    }

    public void add(OrderItem item) {
        add(item.getQuantity(), item.getProduct());
    }

    public double getTotal() {
        double total = 0;
        for (OrderItem item: items.values()) {
            total += item.getAmount();
        }
        return total;
    }
    // ...
}

现在您可以从产品 ID 列表中构建您的订单,如下所示:

    List<Integer> items = Arrays.asList(8, 2, 2, 2);
    Order order = new Order();
    for (int id: items) {
        order.add(catalogue.getProductById(id));
    }

然后用getTotal()计算总数:

    System.out.println(order.getTotal());

【讨论】:

  • 谢谢莫里斯。该程序接受烘焙食品的订单 - 总数量以及作为输入的代码。例如 10 个松饼。每个项目都有一组可用的包裹(比如 2、5、8),每个都有它的成本。我使用硬币找零算法分解了可用包装中的 10 个松饼。例如输入 = 10 个松饼 预期输出:14 个松饼 $54.8 1 x 8 $24.95 3 x 2 $9.95。我已经从算法中分解了包,现在我正在寻找设置 OO 设计以实现输出的最佳方法。
  • 我已经编辑了上面对我的问题的描述,以便更好地解释预期的输出
  • 好的,如果我理解正确的话,如果你想要 n 个松饼,程序必须给出总共至少 n 个松饼的细目,这样成本最低?
  • 不,我不明白:要吃 10 个松饼,我需要一包 8 个和一包 2 个,不是吗?
  • 程序不必优化成本。它必须根据该项目的可用包裹细分总数,并返回与总订单和成本相匹配的任何组合。抱歉,我上面的评论中有错字,我已经修复了上面的问题描述。这是14个松饼。我误写了 10。
【解决方案2】:

有很多方法可以解决这个问题。我将向您介绍几种可能性。

  1. 第一种可能的方法是创建一个包含键、值和重复数的新对象。这是一种很好的方法,因为您在一个对象中拥有所有需要的数据。

具体实现见下文:

public class MyObject{
    private int id;
    private double value;
    private int numberOfDuplicates;

    public MyObject(){
        this.id = 0;
        this.value = 0;
        this.numberOfDuplicates = 0;    
    }

    public MyObject(int id, double value, int numberOfDuplicates){
        this.id = id;
        this.value = value;
        this.numberOfDuplicates = numberOfDuplicates;    
    }

    // INSERT GETTERS AND SETTERS BELOW
}

那你就这样用吧:

public static void packagesprint() {
        List<Integer> items = Arrays.asList(8, 2, 2, 2);
        List<MyObject> myObjectList =  ArrayList<>();

        Map<Integer, Long> result = items.stream()
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

        for (Map.Entry<Integer,Long> entry : result.entrySet()){
            MyObject myObject = new MyObject();
            myObject.setId(entry.getKey());
            myObject.setNumberOfDuplicates(entry.getValue().intValue()); 
            myObject.setValue(value); // <- this is where you set your value, e.g. if 2's value is 5.50, then set 5.50 as value 
            myObjectList.add(myObject);
        }

}
  1. 另一种可能的方法是您可以使用HashMap 并将2 设置为键,将“5.50”设置为值。这种方法的一个缺点是您仍然需要在另一个地图(在您的情况下为 result 地图)中搜索重复数的值。

具体实现见下文:

public static void packagesprint() {
        List<Integer> items = Arrays.asList(8, 2, 2, 2);
        Map<Integer, Double> keyValuePairs = new HashMap<Integer, Double>();

        Map<Integer, Long> result = items.stream()
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

        for (Map.Entry<Integer,Long> entry : result.entrySet()){
            keyValuePairs.put(entry.getKey(), value) // <- this is where you set your value, e.g. if 2's value is 5.50, then set 5.50 as value 
        }
}

【讨论】:

    猜你喜欢
    • 2016-10-05
    • 2022-01-23
    • 1970-01-01
    • 2021-10-26
    • 2015-06-22
    • 1970-01-01
    • 2023-04-06
    • 2010-12-06
    • 1970-01-01
    相关资源
    最近更新 更多