java 我不能列出所有重复的文字,使用流

gg0vcinb  于 2023-03-21  发布在  Java
关注(0)|答案(3)|浏览(98)

我有以下问题:
目标:我想要“City”的所有示例,这些示例具有基于“name”的重复项。
限制:我需要使用流。
错误:没有错误。
描述:
我有一个类“City”的示例列表。目标是使用stream创建一个列表,其中包含基于“name”找到的所有重复项,而不仅仅是一个。
我试图研究我的问题的答案,但所有的答案都只解释了如何添加重复一次的元素,而不是两次或三次,如果情况需要的话。
我发现的研究材料:
Java 8, Streams to find the duplicate elements
https://mkyong.com/java8/java-8-find-duplicate-elements-in-a-stream/
再次目标:随着列表显示在下面,一个新的列表,将被创建,以采取在重复,将有内instace的“Lisboa”3x,instace的“Braga”3x和instace的“Guarda”2x,这是因为这些是重复的元素的基础上的名称。
编辑:谢谢大家的回复。当我分析你们的回复时,我可以看到我可能错过了关于目标的一个重要细节。
在你的回答中,我确实可以看到你在把重复的名字逐字地添加到一个列表中。
然而,我的初衷是让所有“City”类型的示例都有重复的名称。
根据答案,我没有访问的属性。
谢谢你。
主要:

public class Main {
    public static void main(String[] args) {
        List<City> portugalCities = List.of(
                new City("Lisboa", "Estremadura", 2275591),
                new City("Lisboa", "Estremadura", 2275591),
                new City("Faro", "Algarve", 67650),
                new City("Braga", "Minho", 193324),
                new City("Braga", "Esposende", 193324),
                new City("Braga", "Fafe", 193324),
                new City("Alentejo", "Ribatejo", 704533),
                new City("Viseu", "Beira Alta", 99561),
                new City("Lisboa", "Alenquer", 2275591),
                new City("Guarda", "Almeida", 143019),
                new City("Guarda", "Aguiar da Beira", 143019)
        );
    }
}

城市:

public class City {
    private String name;
    private String province;
    private int population;
    // ----- Properties

    public City(String name, String province, int population) {
        this.name = name;
        this.province = province;
        this.population = population;
    }
    // ----- Constructor

    public String getName() {
        return name;
    }

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

    public String getProvince() {
        return province;
    }

    public void setProvince(String district) {
        this.province = district;
    }

    public int getPopulation() {
        return population;
    }

    public void setPopulation(int population) {
        this.population = population;
    }
    // ----- Getter & Setters

    @Override
    public String toString() {
        return String.format("|name: %s; district: %s; population: %s|", name, province, population);
    }
    // ----- toString

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        City city = (City) o;
        return population == city.population && Objects.equals(name, city.name) && Objects.equals(province, city.province);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, province, population);
    }

    // ----- Equals & hashCode
}
wxclj1h5

wxclj1h51#

首先收集名字并计数,然后使用它来筛选出非欺骗者:

Map<String, Long> freq = portugalCities.stream()
  .map(City::getName)
  .collect(groupingBy(n -> n, counting()));

List<City> dupes = portugalCities.stream()
  .filter(c -> freq.get(c.getName()) > 1)
  .collect(toList());

然后按你喜欢的方式打印出来:

dupes.forEach(System.out::println);
w8ntj3qf

w8ntj3qf2#

理想情况下,流一次处理一个元素,而不需要存储中间结果。但是在这种情况下,我们需要存储按名称分组的城市,因为我们无法知道哪些是重复的,除非我们处理了所有元素。因此,给定类City的定义和问题的数据集,我提出了以下两步过程:

Map<String, List<City>> citiesByName =
  portugalCities.stream().collect(Collectors.groupingBy(City::getName));
List<City> result =
  citiesByName.values().stream()
    .filter(list -> list.size() > 1)
    .flatMap(List::stream)
    .toList();

可以在一个更好的单链中完成,但仍然有一个中间结果,citiesByName
结果包含 * 所有重复项 *(据我所知,这是问题的对象),而不仅仅是计数。

rta7y2nd

rta7y2nd3#

您可能希望使用自定义收集器来实现这一点,这与https://mdn.io/Array.reduce不同:
此示例生成输出:

{Alentejo=1, Braga=3, Faro=1, Guarda=2, Lisboa=3, Viseu=1}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.experimental.Accessors;

import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collector;

public class Example {

    public static void main(String[] args) {

        List<City> portugalCities = List.of(
                new City("Lisboa", "Estremadura", 2275591),
                new City("Lisboa", "Estremadura", 2275591),
                new City("Faro", "Algarve", 67650),
                new City("Braga", "Minho", 193324),
                new City("Braga", "Esposende", 193324),
                new City("Braga", "Fafe", 193324),
                new City("Alentejo", "Ribatejo", 704533),
                new City("Viseu", "Beira Alta", 99561),
                new City("Lisboa", "Alenquer", 2275591),
                new City("Guarda", "Almeida", 143019),
                new City("Guarda", "Aguiar da Beira", 143019)
        );

        Map<String, Integer> counts = portugalCities.stream()
                .collect(Collector.<City, Map<String, Integer>>of(
                        // this means our collector starts by creating a tree map
                        // using the default constructor,
                        // which we passed here
                        TreeMap::new,
                        //
                        // then, process each element collecting to a map.
                        // basically:
                        // [{ name: 'a' }, { name: 'a' }, { name: 'b' }]
                        //  .reduce((acc /* accumulator*/, next) => {
                        //    acc[next.name] = (acc[next.name] || 0) + 1;
                        //    return acc; }, {} /* initial value of acc */)
                        (map, next) -> map.put(next.getName(),
                                map.computeIfAbsent(next.getName(), k -> 0) + 1),
                        // this is not needed, as you only have 1 map
                        // if given, it would be how to combine 2 maps (a, and b)
                        (a, b) -> {
                            throw new UnsupportedOperationException();
                        }
                ));

        System.out.println(counts);
    }

    @AllArgsConstructor
    @Accessors(chain = true)
    @Data
    static class City {
        private String name;
        private String province;
        private int population;
    }
}

相关问题