为什么在流中执行价格映射后我无法访问itemName?

huangapple go评论81阅读模式
英文:

Why I can't access the itemName after I peform the price mapping in the stream?

问题

以下是翻译好的内容:

class Order{
    List<Item> items = new ArrayList();

    public List<Item> getItems() {
        return items;
    }

    public void setItems(List<Item> items) {
        this.items = items;
    }
}

class Item{

    String name;
    double price;

    public Item(String name, double price) {
        super();
        this.name = name;
        this.price = price;
    }

    public Item() {
    }

    public static void main(String[] args){
        Item i1 = new Item("Soap", 3.9);
        Item i2 = new Item("Plate", 15.9);
        Item i3 = new Item("Wok", 199.9);

        Order order = new Order();
        order.setItems( Arrays.asList( i1, i2, i3 ) );
        List<Item> items = order.getItems();
        
        // 在这里进行更改,以便获取商品名称
        List<String> itemNames = items.stream().map(elem -> elem.name).collect(Collectors.toList());
        itemNames.forEach(System.out::println);
        
        List<Double> subTtl = items.stream().map(elem -> elem.price * 1.06).collect(Collectors.toList());
        subTtl.forEach(System.out::println);
        
        double ttl = subTtl.stream().mapToDouble(Number::doubleValue).summaryStatistics().getSum();
        System.out.println("Total Payment without tax: " + ttl);
        System.out.println("Total Payment: " + ttl * 1.10);
    }
}
英文:

May I know does java stream allows us to access back the itemName from the subTtl list?
The reason of accessing itemName is because I want to output the data similar as below but the data will be form in the array format.
The expected output will be
like this

class Order{
List&lt;Item&gt; items = new ArrayList();
public List&lt;Item&gt; getItems() {
return items;
}
public void setItems(List&lt;Item&gt; items) {
this.items = items;
}
}
class Item{
String name;
double price;
public Item(String name, double price) {
super();
this.name = name;
this.price = price;
}
public Item() {
}
public static void main(String[] args){
Item i1 = new Item(&quot;Soap&quot;, 3.9);
Item i2 = new Item(&quot;Plate&quot;, 15.9);
Item i3 = new Item(&quot;Wok&quot;, 199.9);
Order order = new Order();
order.setItems( Arrays.asList( i1, i2, i3 ) );
List&lt;Item&gt; items = order.getItems();
List&lt;Double&gt; subTtl = items.stream().map(elem -&gt; elem.price * 1.06).collect(Collectors.toList());
subTtl.forEach(System.out::println);
double ttl = subTtl.stream().mapToDouble(Number::doubleValue).summaryStatistics().getSum();
System.out.println(&quot;Total Payment without tax: &quot; + ttl);
System.out.println(&quot;Total Payment: &quot; + ttl * 1.10);
}
}

答案1

得分: 2

itemNameItem的一个成员。只有从包含Item的流/集合中才能保证访问正确的itemName。你可以实现你想要的,但你必须从List<Item> items开始流式传输。然而,从列表中流式传输并执行除主要工作以外的任何其他操作都被视为“副作用”(副作用不是“纯函数”并且通常被认为不是最理想的)。

因此,最终你会得到类似这样的代码(未经测试):

items.stream().forEach(item -> System.out.println(item.getName() 
+ "\t" + item.getPrice() 
+ "\t" + (item.getPrice() * 0.06) 
+ "\t" + (item.getPrice() * 1.06));
double grandTotal = items.stream().reduce(0, Integer::sum) * 1.06;
System.out.println("GRAND TOTAL:\t\t\t" + grandTotal);
double serviceTax = grandTotal * 0.1;
System.out.println("SERVICE TAX:\t\t\t" + serviceTax);
double totalPayment = grandTotal * 1.1;
System.out.println("TOTAL PAYMENT:\t\t\t" + totalPayment); 

我已经为需要暴露的类变量添加了getter方法。我还假设布局不需要与您的图像布局完全相同 - 如果需要,您可以使用填充文本将事物正确对齐,但这可能比较费力,不过根据是否商业/作业性质,您可能希望进行修改。我还建议封装显示总金额、服务税和总付款的方法,这样您只需要调用单行函数,函数名更接近于:

displayGrandTotal(items);
displayServiceTax(items);
displayTotalPayment(items);

希望这对您有所帮助。

英文:

itemName is a member of Item. You could only guarantee access to the correct itemName from a stream/collection containing Items. Its possible to get what you want but you'd have to start streaming from the List&lt;Item&gt; items. However to stream over a list and perform anything other than one main job would be considered a "side effect" (side effects are not "pure functions" and generally considered less than ideal).

So you'd ultimately have something like (untested):

items.stream().foreach(item -&gt; System.out.println(item.getName() 
+ &quot;\t&quot; + item.getPrice() 
+ &quot;\t&quot; + (item.getPrice() * 0.06) 
+ &quot;\t&quot; + (item.getPrice() * 1.06));
double grandTotal = items.stream().reduce(0, Integer::sum) * 1.06;
System.out.println(&quot;GRAND TOTAL:\t\t\t&quot; + grandTotal);
double serviceTax = grandTotal * 0.1;
System.out.println(&quot;SERVICE TAX:\t\t\t&quot; + serviceTax);
double totalPayment = grandTotal * 1.1;
System.out.println(&quot;TOTAL PAYMENT:\t\t\t&quot; + totalPayment); 

I've taken the liberty to add getters for the class variables that need to be exposed. I've also assumed the layout doesn't need to be exactly the same as your image layout - for that you'd want to use padded text to line things up correctly but that will be more effort than its likely worth but you may wish to amend depending on whether this is commercial/homework. I'd also consider encapsulating the methods for displaying the grand total, service tax and total payment so you can just call a single line function whose name is more along the lines of

displayGrandTotal(items);
displayServiceTax(items);
displayTotalPayment(items);

Hopefully this is useful

huangapple
  • 本文由 发表于 2020年9月22日 12:57:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/64003298.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定