根据Java中对象属性的最常见值过滤对象的Arraylist

时间:2018-03-29 14:06:38

标签: java object variables arraylist filter

我试图根据对象变量的值过滤Java对象的ArrayList。

对不起,如果这听起来很混乱。也许代码会更好地解释它。

public static void main(String[] args)
{
    ArrayList<Data> list = new ArrayList<>();

    list.add(new Data("Uvumvew", 10));
    list.add(new Data("Uvumvew", 10));
    list.add(new Data("Uvumvew", 10));
    list.add(new Data("Uvumvew", 11));
    list.add(new Data("Uvumvew", 14));
    list.add(new Data("Uvumvew", 14));
    list.add(new Data("Ossas", 5));
    list.add(new Data("Ossas", 5));
    list.add(new Data("Ossas", 10));
    list.add(new Data("Ossas", 10));
    list.add(new Data("Ossas", 10));
    list.add(new Data("Dummy", 7));
    list.add(new Data("Dummy", 7));
    list.add(new Data("Dummy", 7));
    list.add(new Data("Dummy", 8));
    list.add(new Data("Dummy", 8));
}

和对象

private String name;
private double value;

public Data() {
}

public Data(String name, double value) {
    super();
    this.name = name;
    this.value = value;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public double getValue() {
    return value;
}

public void setValue(double value) {
    this.value = value;
}

你可以看到arraylist中会有重复。我只能在它成为arraylist之后才能过滤它,因为我正在读取文件然后将它放入ArrayList。

我尝试实现的输出看起来像这样

Uvumvew,10
Ossas,10
Dummy,7

因为10,10,7分别是Uvumvew,Ossas和Dummy最常见的值。我已经尝试使用Collection并过滤值,但由于Object中包含重复值,因此无法实现。

我的尝试就像这样

Collection<Data> nonDuplicatedName = list.stream()
               .<Map<String, Data>> collect(HashMap::new,(m,e)->m.put(e.getName(), e), Map::putAll)
               .values();

它产生这样的输出是错误的

Dummy 8.0
Uvumvew 14.0
Ossas 10.0

对我理解的任何帮助或更正都将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:3)

这可能有点过于复杂,使用中间地图会产生开销,但这可以解决您的问题:

Map<String, Map<Double,Long>> tmpMap = list.stream()
        .collect(
                groupingBy(Data::getName,
                        groupingBy(Data::getValue,counting())
                ));
// {Dummy={8.0=2, 7.0=3}, Ossas={10.0=3, 5.0=2}, Uvumvew={10.0=3, 11.0=1, 14.0=2}}

让我们先计算原始Data#value的频率。因此,我们只需按Data#name拳头分组,即可获得相似对象的地图,然后按Data#value分组并同时计算单个value出现的次数。这将为Map提供keys Data#names valuesData#values频率Uvumvew={10.0=3, 11.0=1, 14.0=2} Data 现在有了这张地图,我们可以创建一个价值最高的新tmpMap个对象 - 只需迭代Map#key并使用Data#name构建新对象{10.0=3, 11.0=1, 14.0=2}和最大元素来自嵌套频率图Data#valuetmpMap.entrySet() .stream() .map( entry -> new Data( entry.getKey(), entry.getValue().entrySet().stream() .max(Map.Entry.comparingByValue()).get().getKey() ) ).collect(toList()); //[Data{name='Dummy', value=7.0}, Data{name='Ossas', value=10.0}, Data{name='Uvumvew', value=10.0}]

path[0]

我希望这会有所帮助。