动态多选项分组的复杂哈希图数据结构,以改进在任意数据上运行分组的实现



我正在编写一个程序,该程序将针对文件中的所有数字列对任意文件(没有数据的先验知识)的每个特征列运行 groupby。我希望这个过程非常快,但我希望它首先工作。我有两个问题:

1). 就如何直观地表示这个复杂的 HashMaps 数据结构列表而言,以下理解是否正确(在评论中描述)?

    List<HashMap<String, ArrayList<HashMap<String, Number>>>> finalResult = 
            new ArrayList<HashMap<String, ArrayList<HashMap<String, Number>>>>();
        /**
         * Result should contain something like this for population and other metrics:
         * [{population={state={Virginia=20000000, Texas=200000, NY=30000000}, 
         *      {Country={Africa=30000000, India=400000000}}, 
         *  {Temperature={state={Virginia=83, Texas=92, NY=72},
         *      {Country={Africa=90, India=88, England=65, Canada=69}}}},
         *  {LifeExpectancy={state={Virginia=77, Texas=83, NY=67},
         *      {Country={Africa=90, India=88, England=65, Canada=69}}}}]
         */

2). 有没有更智能的方法来存储所有这些信息?改进此数据结构设计的任何想法?它基本上将存储聚合类型的列表和每个功能列的数字指标。

这是一个示例文件(顺便说一下,它可以是任何类型的文件):

id;state;city;total_pop;avg_temp
1;Florida;;120000;76
2;Michigan;Detroit;330000;54
3;New Jersey;Newark;;34
4;Florida;Miami;200000;80
5;New Jersey;Jersey City;1200000;55

提前谢谢你。

拥有一个包含这些属性的 CountryState 对象会更容易。然后,您可以使用自定义Comparator进行排序。然后你最终会得到这样的东西:

Map<String, List<Country>> countryStatistics = new Map<>();    
countryStatistics.put(
    "population", 
    new ArrayList<Country>(
        Collections.sort(
            countries, 
            new Comparator<Country>() {
                int compare(Country c1, Country c2) {
                    return c1.getPopulation() - c2.getPopulation();
                }
            }
        )
    )
);

依此类推,对于每个类别。然后,您将拥有一张地图,该地图将每个统计数据映射到按该统计数据排序的国家/地区排序列表。

根据您的编辑,对于任意数据,您可以执行以下操作:

//there's probably a better name for this, but let's go with this for now
public class Data {
    private Map<String, Integer> attributes = new HashMap<>();
    public Integer getValue(String attribute) {
        return attributes.get(attribute); //This doesn't handle cases where
                                          //the attribute doesn't exist. Maybe
                                          //you want to return 0 for that. 
    }
    public Integer setValue(String attribute, Integer value) {
        attributes.put(attribute, value);
    } 
}

然后你会做类似的事情:

Map<String, List<Data>> dataStatistics = new Map<>();    
dataStatistics.put(
    "population", 
    new ArrayList<Country>(
        Collections.sort(
            countries, 
            new Comparator<Country>() {
                @Override
                public int compare(Country c1, Country c2) {
                    return c1.getValue("population") - c2.getValue("population");
                }
            }
        )
    )
);

如果不想重复代码,可以创建一个工厂方法,该方法返回基于指定属性进行排序的Comparator实例:

public Comparator<Data> createComparatorForAttribute(final String attribute) {
    return new Comparator<Data>() {
        @Override
        public int compare(Data d1, Data d2) {
            return d1.getValue(attribute) - d2.getValue(attribute);
        }
    };
}

最新更新