Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 根据两个对象对列表中的元素进行分组,如果它们具有相同的值,则只显示元素一次,并显示计数_Java_List_Collections_Java Stream_Grouping - Fatal编程技术网

Java 根据两个对象对列表中的元素进行分组,如果它们具有相同的值,则只显示元素一次,并显示计数

Java 根据两个对象对列表中的元素进行分组,如果它们具有相同的值,则只显示元素一次,并显示计数,java,list,collections,java-stream,grouping,Java,List,Collections,Java Stream,Grouping,我有一段代码如下: List locationList=getLocations(位置、eventTypeList、eventIdentityData); 这给了我一个位置列表 我的Location.java类如下: 私人字符串城市; 私人国家; 私人双纬度; 私人双经度; 他们也有接受者和接受者 因此,如果我得到如下输出: "locations": [ { "city": "Dubai", "country": "United Arab Emirat

我有一段代码如下:

List locationList=getLocations(位置、eventTypeList、eventIdentityData);
这给了我一个位置列表

我的Location.java类如下:

私人字符串城市;
私人国家;
私人双纬度;
私人双经度;
他们也有接受者和接受者

因此,如果我得到如下输出:

"locations": [
    {
        "city": "Dubai",
        "country": "United Arab Emirates",
        "latitude": 25.2048493,
        "longitude": 55.2707828
    },
    {
        "city": "Dubai",
        "country": "United Arab Emirates",
        "latitude": 25.2048493,
        "longitude": 55.2707828
    },
    {
        "city": "Delhi",
        "country": "India",
        "latitude": 10.2048493,
        "longitude": 40.2707828
    }
]
在上面的响应中,有两个元素具有相同的纬度和经度值,因此这些元素应分组在一起,并显示为一个元素,计数为2。输出应如下所示:

"locations": [
    {
        "city": "Dubai",
        "country": "United Arab Emirates",
        "latitude": 25.2048493,
        "longitude": 55.2707828,
        "count": 2
    },
    {
        "city": "Delhi",
        "country": "India",
        "latitude": 10.2048493,
        "longitude": 40.2707828,
        "count": 1
    }
]

我知道我需要做的一件事是在Location类中声明count变量。此外,这意味着我需要根据纬度和经度值进行分组(要将元素分组在一起,这两个值必须相同)。有人能帮我根据我需要的输出修改这个列表吗?

使用一个流,以其组合纬度和经度的唯一表示形式对位置进行分组。然后将计数设置为每个组的大小

private static Collection<Location> count(Collection<Location> input) {
    return input.stream()
                .collect(groupingBy(locaction -> BigDecimal.valueOf(locaction.getLatitude()).setScale(7, ROUND_DOWN).toPlainString() +
                                                 BigDecimal.valueOf(locaction.getLongitude()).setScale(7, ROUND_DOWN).toPlainString()))
                .values().stream()
                .map(locations -> locations.get(0).setCount(locations.size()))
                .collect(toList());
}
私有静态收集计数(收集输入){
返回input.stream()
.collect(groupingBy(locaction->BigDecimal.valueOf(locaction.getLatitude()).setScale(7,向下舍入).toPlainString()+
BigDecimal.valueOf(locaction.getLongitude()).setScale(7,向下舍入).toPlainString())
.values().stream()
.map(位置->位置.get(0).setCount(位置.size())
.collect(toList());
}
例如:

public class Main {

    public static void main(String[] args) {
        Location location1 = new Location("a", "b", 1.23232321, 4.56);
        Location location2 = new Location("c", "d", 1.23232328, 4.56);
        Location location3 = new Location("e", "f", 7.89, 0.12);
        Collection<Location> count = count(Arrays.asList(location1, location2, location3));
        System.out.println(count);
    }

    private static Collection<Location> count(Collection<Location> input) {
        return input.stream()
                    .collect(groupingBy(locaction -> BigDecimal.valueOf(locaction.getLatitude()).setScale(7, ROUND_DOWN).toPlainString() +
                                                     BigDecimal.valueOf(locaction.getLongitude()).setScale(7, ROUND_DOWN).toPlainString()))
                    .values().stream()
                    .map(locations -> locations.get(0).setCount(locations.size()))
                    .collect(toList());
    }

    public static class Location implements Serializable {
        private String city;
        private String country;
        private double latitude;
        private double longitude;
        private int count;

        public Location(String city, String country, double latitude, double longitude) {
            this.city = city;
            this.country = country;
            this.latitude = latitude;
            this.longitude = longitude;
        }

        public double getLatitude() {
            return latitude;
        }

        public double getLongitude() {
            return longitude;
        }

        public Location setCount(int count) {
            this.count = count;
            return this;
        }
    }
}
公共类主{
公共静态void main(字符串[]args){
位置1=新位置(“a”、“b”、1.2321、4.56);
位置2=新位置(“c”、“d”、1.2328、4.56);
位置3=新位置(“e”、“f”、7.89、0.12);
集合计数=计数(Arrays.asList(location1、location2、location3));
系统输出打印项次(计数);
}
私有静态集合计数(集合输入){
返回input.stream()
.collect(groupingBy(locaction->BigDecimal.valueOf(locaction.getLatitude()).setScale(7,向下舍入).toPlainString()+
BigDecimal.valueOf(locaction.getLongitude()).setScale(7,向下舍入).toPlainString())
.values().stream()
.map(位置->位置.get(0).setCount(位置.size())
.collect(toList());
}
公共静态类位置实现可序列化{
私人城市;
私人国家;
私人双纬度;
私人双经度;
私人整数计数;
公共位置(字符串城市、字符串国家、双纬度、双经度){
this.city=城市;
这个国家=国家;
这个。纬度=纬度;
这个经度=经度;
}
公共双纬度(){
返回纬度;
}
公共双getLongitude(){
返回经度;
}
公共位置设置计数(整数计数){
this.count=计数;
归还这个;
}
}
}

请注意,确定两个浮点数相等可能很困难。要将两个位置组合在一起,这些坐标必须有多近?要将它们组合在一起,这些坐标必须完全相同,因为我必须在地图上渲染这些数据。精确程度如何?
1.2345678
等于
1.23456789
?我只需要检查小数点后7位。当我使用Google Geo API解析地址(这些地址只不过是机场的IATA代码)时,它给出的值是完全相同的,无论是高达1个小数点还是100个小数点。因此,如果我通过“DEL”进行解析,它每次都给我相同的纬度和经度。也让我们暂时考虑它们是字符串,我必须操作我的列表,我怎么做?这些位置是否有<代码>等于和<代码> HASCODE < /代码>实现?您可以使用
locations.stream().collect(Collectors.groupingBy(Function.identity(),Collectors.counting())
否则,您必须将
Function.identity()
替换为
l->array.asList(l.getCity(),l.getCountry(),l.getlatitudio(),l.getLongitude())
我正在使用您上面给出的代码,使用更改,如Collector.groupingBy()而不仅仅是groupingBy,以及Collector.toList()而不仅仅是toList。但是我得到了一个编译错误:无法推断collect(CollectorI)的类型参数,我发现了我的代码的问题,尽管它已经作为您的代码的一部分被提到。我的计数设置程序不同。这段代码对我来说非常好,并且完全符合要求。