Открытый поток внутри потока - PullRequest
0 голосов
/ 25 мая 2018

У меня есть этот фрагмент кода.Как я могу преобразовать это?к функциональному стилю?На самом деле у меня есть List<X>.каждый X содержит List<V>.Каждый V в этом списке имеет List<M> в качестве параметра.И мне нужно построить Map<X,Y>, где Y - это количество всех M объектов, которые хранятся во всех V объектах, агрегированных в объекте X.

HashMap<Country, Integer> modelsPerCountryMap = new HashMap<>();
int count;
for (Country country : CountryDataSingleton.getCountryDataCollection()) {
    count = 0;
    for (CarMaker cm : country.getListOfMakers()) {
        count += cm.getModels().size();
    }
    modelsPerCountryMap.put(country, count);
}

Ответы [ 3 ]

0 голосов
/ 25 мая 2018

Что примерно так:

открытый класс CountryFunctionalTest {

private class CarMaker {

    private final String name;
    private final List<String> models;

    public CarMaker(String name, List<String> models) {
        this.name = name;
        this.models = models;
    }

    public String getName() {
        return name;
    }

    public List<String> getModels() {
        return models;
    }
}

private class Country {

    private final String name;
    private final List<CarMaker> makers;

    public Country(String name, List<CarMaker> makers) {
        this.name = name;
        this.makers = makers;
    }

    public String getName() {
        return name;
    }

    public List<CarMaker> getMakers() {
        return makers;
    }
}

@Test
public void test() throws DeliveryException {
    List<Country> countries = Arrays.asList(new Country[]{
            new Country("Country A", Arrays.asList(new CarMaker[]{ new CarMaker("Maker A", Arrays.asList(new String [] {"model a", "model a1", "model a2"})) })),
            new Country("Country B", Arrays.asList(new CarMaker[]{ new CarMaker("Maker B", Arrays.asList(new String [] {"model b", "model b1"})) })),
            new Country("Country C", Arrays.asList(new CarMaker[]{ new CarMaker("Maker C", Arrays.asList(new String [] {"model c", "model c1", "model c2", "model c3"})) }))
    });

    Map<Country, Integer> conuntriesModels = IntStream.range(0, countries.size()).mapToObj(i -> new AbstractMap.SimpleEntry<Country, Integer>(countries.get(i),
            IntStream.range(0, countries.get(i).getMakers().size())
                .map(ix -> countries.get(i).getMakers().get(ix).getModels().size()).sum()
                )
            ).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

    for (Country next : conuntriesModels.keySet()) {
        System.out.println(next.getName() + " models -> " + conuntriesModels.get(next));
    }
}

}

Вывод:

Модели страны B -> 2

Модели Country A -> 3

Модели Country C -> 4

0 голосов
/ 17 июня 2018

Если вы собираетесь работать в Java, рассмотрите возможность использования vavr.io .Vavr предоставляет вам инструменты, необходимые для применения функциональной парадигмы удобным и последовательным способом.В этом случае неизменные структуры данных .Использование io.vavr.collection.Stream и io.vavr.collection.HashMap, сбор данных в Map<Country, Integer> может выглядеть примерно так:

Stream.ofAll(CountryDataSingleton.getCountryDataCollection())
        .map(country -> Tuple.of(country, country.getListOfMakers().foldLeft(0, (acc, cm) -> acc + cm.getModels().size())))
        .foldLeft(HashMap.<Country, Integer>empty(), (acc, entry) -> acc.put(entry));
0 голосов
/ 25 мая 2018

Я бы передавал страны по странам, а затем собирал их на карту, где ключом является страна, а значением может быть суммарный поток размеров производителей:

Map<Country, Integer> modelsPerCountryMap =
     CountryDataSingleton.getCountryDataCollection()
                         .stream()
                         .collect(
                             Collectors.toMap(
                                 Function.identity(),
                                 c -> c.getListOfMakers()
                                       .stream()
                                       .mapToInt(cm -> cm.getModels().size())
                                       .sum()
                              )
                         );
...