【问题标题】:Building a location hierarchy of counts建立计数的位置层次结构
【发布时间】:2016-11-02 14:42:42
【问题描述】:

我有以下位置层次结构:

public class Location {
   public Location parentLocation;
   public String name;
   public int id;
}

List<Location> listOfCities; // This list strictly contains all "city" level locations like Chicago, Atlanta etc.

让我们假设 parentLocation 只能是国家,而国家的 parentLocation 为空。 IE。如果我有芝加哥的位置,则芝加哥位置对象的 parentLocation 将是 USA,并且链将在那里终止,因为位置 USA 的 parentLocation = null。我有一个城市级位置对象列表,我想获得以下计数:

USA (20)
  - Chicago (12)
  - New York (1)
  - Oregon (5)
  - Atlanta (2)
Mexico (1)
  - Puebla (1)

在 Java8 中是否有一种方便的方法来获取一个 jsonable 对象,该对象代表我上面描述的给定城市位置列表的计数层次结构?我的尝试:

// Get counts of all cities in listOfCities (ie. Chicago -> 12)
Map<String, Integer> cityCounts = listOfCities.stream()
.map(Location::name)
.collect(Collectors.toMap(city -> city, city -> 1, Integer::sum));

我不确定如何准确地通过 parentLocation 获取“汇总”计数,并将所有内容放入一个干净的响应对象中,该对象可以以上面漂亮打印的方式行走。

【问题讨论】:

  • 芝加哥有 12 个,因为还有 12 个其他城市是芝加哥的父级城市吗? listOfCities 是所有地点、父母和非父母的List&lt;Location&gt; 吗?
  • @4castle Chicago 有 12 个,因为有 12 个城市的 String name = "Chicago"。 listOfCities 是一个 List 所有非父母(即城市级别的 Location 对象)。城市之外没有位置级别,并且城市的 parentLocation = country。
  • 谢谢,这一切都清楚了。 USA 是否会作为键包含在输出 Map 中?
  • 看来您是本末倒置。首先弄清楚你要构建什么结构,然后让我们看看 Java 8 是否可以提供帮助
  • 也许你想要Map&lt;String, Map&lt;String, Integer&gt;&gt;?外层地图是国家,内层地图是城市及其数量。请edit您的问题与您想要的输出结构。

标签: java java-8


【解决方案1】:

您可以生成Map&lt;String, Map&lt;String, Long&gt;&gt;,在外部地图中使用国家名称,在内部地图中使用城市名称/计数。

import static java.util.stream.Collectors.*;

Map<String,Map<String,Long>> cityCountsByCountry = listOfCities
    .stream()
    .collect(groupingBy(city -> city.parentLocation.name,
                 groupingBy(city -> city.name,
                     counting())));

这将产生一个类似于此 JSON 的结构:

{
  "USA": {
    "Chicago": 12,
    "New York": 1,
    "Oregon": 5,
    "Atlanta": 2
  },
  "Mexico": {
    "Puebla": 1
  }
}

【讨论】:

  • 需要在分组中添加空检查... city -&gt; city.parentLocation == null ? city.name : city.parentLocation.name
  • @Bolzano listOfCities 中的所有元素都是城市。他们都不会有null 作为父母。
  • meh.. 我认为有一个更大的挑战,例如列表包含除 nvm 之外的所有内容,这按预期工作,很好。
  • @Bolzano 如果列表确实包含所有位置,那么我会在collect 之前放置一个filter,它会过滤掉具有null 父级的元素。或者,我会回去给没有城市的任何国家提供一张空白的内部地图。
  • @shmosel 只需将每个内部地图中的计数相加即可找到国家/地区的总数。该操作非常简单,将其放入 JSON 中将是多余的,因为它可以派生。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-11
  • 1970-01-01
  • 2017-10-04
相关资源
最近更新 更多