【问题标题】:sum by group inside a looping of list object in java在java中的列表对象循环内按组求和
【发布时间】:2016-04-06 09:47:19
【问题描述】:

我一直坚持从我拥有的列表对象创建小计。像这样的代码,

private List<Object> getData() {
    List<Object> items = new ArrayList<>();
    List<Object> objectList = dataBaseHelper.fetchData();

 for (Object obj : objectList) {
    items.add(new Object(obj.one, obj.two));
 }

return items;

}

我可以把列表做得很好,就像

a 1
a 2
a 3
b 1
b 2
b 3

但我想这样列出我的清单,

    a       1
    a       2
    a       3
subTotal a  6

    b       1
    b       2
    b       3
subTotal b  6

有人可以指导我如何做到这一点吗?

之前谢谢,

【问题讨论】:

  • ObjectClass 究竟是什么?
  • @kazenorin 这只是一个例子,比如汽车等,我就我的问题举一个简单的例子,你能给我一个提示来实现我想要的吗?

标签: java list object for-loop


【解决方案1】:

好吧,我试着用一种有点抽象的方式回答。

首先让事情变得不那么模棱两可,让我们假设dataBaseHelper.fetchData() 返回一个List&lt;MyObject&gt;,其中MyObject 具有以下成员:

  • public String name;
  • public int price;

现在假设我们要计算按名称分组的小计。然后我们需要一个可以保存这样数据的数据结构。为了简单起见,我们只使用列表地图:

Map&lt;String, List&lt;MyObject&gt;&gt; subTotalsByName = new HashMap&lt;&gt;();

然后我们可以循环遍历返回的数据:

private Map<String, List<MyObject>> getData() {
  Map<String, List<MyObject>> subTotalsByName = new HashMap<>();
  List<MyObject> objectList = dataBaseHelper.fetchData();

  for (MyObject obj : objectList) {
    List<MyObject> subTotalList = subTotalsByName.get(obj.name);
    if (subTotalList == null){
        subTotalList = new ArrayList<>();
        subTotalsByName.put(obj.name, subTotalList);
    }

    subTotalList.add(obj);
  }

  return subTotalsByName;
}

(注:以上代码未经测试,将其视为伪代码,只是为了给您一个按小计分组的想法)

现在你有一个MapListMyObjects,现在你只需要遍历计算小计的地图! (事实上​​,这可能在上面的循环中更早完成,但是为了让事情更清楚,我们浪费了更多的 CPU 周期来显式地做一些事情。不做过早的优化也是一个好主意:))

for (Entry<String, List<MyObject>> entry : subTotalsByName.entrySet()) {

  int subtotal = 0;

  List<MyObject> myObjects = entry.getValue();
  for (MyObject myObj : myObjects){
    System.out.println(myObj.name + " " + myObj.price);
    subtotal += myObj.price;
  }

  System.out.println("subTotal for " + entry.getKey() + " is " + subtotal);
  System.out.println();
}

(同样,这是未经测试的,视为伪代码)

然后你会得到这样的输出:

a 1
a 2
a 3
subTotal for a is 6

b 4
b 5
b 6
subTotal for b is 15

【讨论】:

  • 我一直在测试它,但是我在这行代码subTotalsByName.put(subTotalList); 中遇到了这个错误,在我的代码中错误是:put(java.lang.String, List) in Map不能应用于 (java.util.List)
  • 应该是subTotalsByName.put(obj.name, subTotalList);,因为Map.put(key, value)需要两个参数
  • 感谢代码有效,它给了我想要的结果。问题是,我不想更改其他代码,因为如果我将函数的类型从 List 更改为 Map,我需要更改其他代码。这很令人费解,所以如果函数的类型返回仍然是 List 的任何更改,可以这样做吗?还是不行?
  • 您的意思是您根本不想更改private List&lt;MyObject&gt; getData 的返回类型?如果是这样,那么使用普通的 Java 实践是不可能的,或者说不可能的。至少,您必须更改 List 的泛型类型,例如private List&lt;MyObjectSubtotal&gt; getData,其中 MyObjectSubtotal 是一个包含小计的对象。否则,您将如何区分汇总(小计)和记录(对象)?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-29
  • 2014-11-14
  • 1970-01-01
  • 2021-03-04
  • 1970-01-01
相关资源
最近更新 更多