我试图按Java数组列表元素分组。
我有一个JSONObjects数组,如下所示,我想按字段price和side分组,然后将股票与新字段buyShares和sellShares相加
[{"shares":20,"side":"B","orderId":"001","price":"500"},
{"shares":20,"side":"S","orderId":"002","price":"501"},
{"shares":25,"side":"B","orderId":"003","price":"500"},
{"shares":10,"side":"S","orderId":"004","price":"501"},
{"shares":30,"side":"B","orderId":"005","price":"505"},
{"shares":35,"side":"B","orderId":"006","price":"505"},
{"shares":35,"side":"S","orderId":"007","price":"500"}]
我想按价格和侧边分组,得到如下所示:
[{"price":"500","buyShares":45, "sellShares":35}, {"sellShares":30,"price":"501"}, {"price":"505","buyShares":65}]
我使用以下Java代码:
ArrayList<JSONObject> aOrdersArray = new ArrayList<>(aOrders.values());
System.out.println(aOrdersArray);
List<JSONObject> test = aOrdersArray.stream()
.distinct()
.collect(Collectors.groupingBy(jsonObject -> jsonObject.getInt("price")))
.entrySet().stream()
.map(e -> e.getValue().stream()
.reduce((f1,f2) -> {
JSONObject h = new JSONObject();
h.put("price",f1.get("price"));
System.out.println(f1);
if (f1.get("side").equals("B") && f2.get("side").equals("B")) {
h.put("buyShares", f1.getInt("shares") + f2.getInt("shares"));
}
else if (f1.get("side").equals("S") && f2.get("side").equals("S")) {
h.put("sellShares", f1.getInt("shares") + f2.getInt("shares"));
}
else if (f1.get("side").equals("S")) {
h.put("sellShares", f1.get("shares"));
}
else if (f1.get("side").equals("B")) {
h.put("buyShares",f1.get("shares"));
}
else if (f2.get("side").equals("S")) {
h.put("sellShares", f2.get("shares"));
}
else if (f2.get("side").equals("B")) {
h.put("buyShares",f2.get("shares"));
}
return h;
}))
.map(f -> f.get())
.collect(Collectors.toList());
System.out.println(test);
有时会出现以下错误
Exception in thread "main" org.json.JSONException: JSONObject["side"] not found.
要使用gson,可以创建一个类:
public class Share{
private int shares;
private String side;
private String orderId;
private String price;
//getters and setters
public int getShares() {
return shares;
}
public void setShares(int shares) {
this.shares = shares;
}
public String getSide() {
return side;
}
public void setSide(String side) {
this.side = side;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
然后您可以使用这个从JSON映射object:
String yourJson = "[{\"shares\":20,\"side\":\"B\",\"orderId\":\"001\",\"price\":\"500\"},{\"shares\":35,\"side\":\"S\",\"orderId\":\"007\",\"price\":\"500\"}]";
Gson gson = new Gson();
Type shareListType = new TypeToken<ArrayList<Share>>(){}.getType();
ArrayList<Share> userArray = gson.fromJson(yourJson, shareListType);
你试图做的事情是复杂和容易出错的,因为你的开始是错误的。
您首先就不应该有
正确的开始方法是创建一个表示这样一条记录的Java对象,然后将JSON输入转换为正确的,惯用的Java版本。你想要:
@Value class Record {
int shares;
RecordKind kind;
int orderId;
int price;
public PriceGroup toGroup() {
return new PriceGroup(price,
kind == BUY ? shares : 0,
kind == SELL ? shares : 0);
}
}
@Value class PriceGroup {
int price;
int buyShares;
int sellShares;
public PriceGroup merge(PriceGroup other) {
if (other.price != this.price) throw new IllegalArgumentException();
return new PriceGroup(price,
this.buyShares + other.buyShares,
this.sellShares + other.sellShares);
}
}
注意:使用Lombok's的
。假设这个东西有一个构造函数,所有字段都是final,toString和equals以及hashCode都在正确的位置,等等。
一旦您拥有了上述两种类型,那么您就可以将您的输入JSON转换为一个
list<record> ode="">
。有了这个
当然,该错误将永远不会发生,并且您的MAP/GROUP代码将更容易阅读。您所做的任何错别字都将导致编译时错误。自动完成将工作良好,等等:所有的优点。
要将JSON转换为给定类型,请使用jackson。如果您不想添加该依赖项(确实应该添加),那么在Record类中编写一个
List<Record> orders = ...;
List<PriceGroup> test = orders.stream()
.distinct()
.map(Record::toGroup)
.collect(Collectors.groupingBy(PriceGroup::getPrice))
.entrySet().stream()
.map(e -> e.getValue().stream()
.reduce((f1, f2) -> f1.merge(f2))
.collect(Collectors.toList());
您的代码现在非常容易阅读,所有方法都有正确的名称(它是
问题内容: 我有一个属于每个小组的球员名单。如何使用过滤器列出每个组的用户? 我在寻找这个结果: team alpha Gene team beta George Paula team gamma Steve Scruath of the 5th sector 问题答案: 可以使用angular.filter模块的groupBy。 因此您可以执行以下操作: JS: HTML: 结果: Group
我想使用流API过滤包含哈希映射的数组列表。 上述方法给出了结果列表。现在,我想通过一些条件过滤这个列表,并收集一个新的哈希映射数组列表。 例如,我想选择具有“null”值且字符串具有“parent_item_id”的哈希映射。 我尝试了以下方法。 最后,它起作用了 我用了这个谢谢大家
如何使用匹配数组的多个值从集合中获取对象。例如:我收集了以下数据
问题内容: 有人可以给我看一个简单的示例,如何使用新的lambda语法在Java 8中按字母顺序排序。 问题答案: 对于字符串,这将工作
问题内容: 假设我有一个类似的元组: 我想过滤出列表并生成一个以’img’开头的元素的新列表。因此,我的新列表将如下所示: 谢谢! 问题答案: 单程: 另一种方式: 第一种称为列表理解。有关相关技术,请参见FC的答案。基本语法为。它在语义上等效于以下内容: 该位是可选的,就像在for循环中一样。 第二个是简单的内置函数,它接受测试函数和可迭代函数,并返回一个包含“通过”测试函数的每个元素的列表。,
因此,我有一个,下面的字符串作为元素: null null
问题内容: 我有一个,我想在一行中过滤掉负值(创建一个没有新数组)而不添加循环。使用Java 8 Lambda表达式是否可能? 在python中,将使用生成器: 是否可以在Java 8中做类似的简洁操作? 问题答案: 是的,您可以通过在数组中创建一个,滤除负片,然后将流转换回数组来实现此目的。这是一个例子: 如果要过滤不是的引用数组,则需要使用采用的方法来获取原始类型的数组作为结果:
我创建了一个To-Do-List程序,记录用户输入的任务。对于每个任务,用户必须输入名称、日期等。 当用户从菜单中选择“5”时,程序会按这些任务的日期对它们进行排序。我需要根据任务的日期和时间的升序对所有任务进行排序,即日期和时间较早的任务会排在日期和时间较晚的任务之前,并显示排序后的列表。 然而,当我运行代码时,我会收到以下错误: 下面是我到目前为止的代码:(在底部)