簡體   English   中英

將列表流轉換為單個Container

[英]Convert List stream into single Container

考慮下面的WorkExperience類:

public class WorkExperience {
    private int year;
    private List<Skills> skill;

    public WorkExperience(int year, List<Skills> skill) {
        this.year = year;
        this.skill = skill;
    }   
    //getter setter         
}

public class Skills {
    private String skills;

    public Skills(String skills) {
        this.skills = skills;
    }

    @Override
    public String toString() {
        return "Skills [skills=" + skills + "]";
    }
}     

假設我希望按年份分組我的技能,這就是我們如何按年份groupBy

public static void main(String[] args) {

    List<Skills> skillSet1 = new  ArrayList<>();
    skillSet1.add(new Skills("Skill-1"));
    skillSet1.add(new Skills("Skill-2"));
    skillSet1.add(new Skills("Skill-3"));

    List<Skills> skillSet2 = new  ArrayList<>();
    skillSet2.add(new Skills("Skill-1"));
    skillSet2.add(new Skills("Skill-4"));
    skillSet2.add(new Skills("Skill-2"));


    List<Skills> skillSet3 = new  ArrayList<>();
    skillSet3.add(new Skills("Skill-1"));
    skillSet3.add(new Skills("Skill-9"));
    skillSet3.add(new Skills("Skill-2"));

    List<WorkExperience> workExperienceList = new ArrayList<>();
    workExperienceList.add(new WorkExperience(2017,skillSet1));
    workExperienceList.add(new WorkExperience(2017,skillSet2));
    workExperienceList.add(new WorkExperience(2018,skillSet3));

    Map<Integer, Set<List<Skills>>> collect = workExperienceList.stream().collect(
        Collectors.groupingBy(
            WorkExperience::getYear,
            Collectors.mapping(WorkExperience::getSkill, Collectors.toSet())
        )
    );
}

groupBy返回: Map<Integer, Set<List<Skills>>>
但我需要的是: Map<Integer, Set<Skills>>

如何將List流轉換為單個Container?

使用Java 8功能的flatMapping的替代方案將是

Map<Integer, Set<Skills>> map = workExperienceList.stream()
    .collect(Collectors.toMap(
        WorkExperience::getYear,
        we -> new HashSet<>(we.getSkill()),
        (s1, s2)-> { s1.addAll(s2); return s1; }));

你可以稍微優化一下

Map<Integer, Set<Skills>> map = workExperienceList.stream()
    .collect(Collectors.toMap(
        WorkExperience::getYear,
        we -> new HashSet<>(we.getSkill()),
        (s1, s2) -> {
            if(s1.size() > s2.size()) { s1.addAll(s2); return s1; }
            else { s2.addAll(s1); return s2; }
        }));

我們可以使用Java-9中添加的Collectors.flatMapping 通過使用flatMapping我們可以將中間列表展平為單個容器。 flatMapping可用於原始流的元素可轉換為流的情況。

workExperienceList.stream().collect(Collectors.groupingBy(
                              WorkExperience::getYear, 
                              Collectors.flatMapping(workexp -> workexp.getSkill().stream(), 
                                             Collectors.toSet())));

API注意

flatMapping()收集器在多級縮減中使用時非常有用,例如groupingBy或partitioningBy的下游。

另一種實現所需方法的方法是使用靜態工廠方法Collector.of()實現自己的收集Collector.of()

Map<Integer, Set<Skills>> collect = workExperienceList.stream()
    .collect(Collector.of(
        HashMap::new,
        ( map, e ) -> map.computeIfAbsent(e.getYear(), k -> new HashSet<>()).addAll(e.getSkill()),
        ( left, right ) -> {
            right.forEach(( year, set ) -> left.computeIfAbsent(year, k -> new HashSet<>()).addAll(set));
            return left;
        })
    );

與其他答案相比,這是相當混亂和臃腫。

嘗試更加面向對象。 所以我想創建一個新的小對象

public static class AsGroup {
    private final Integer year;
    private final Collection<Skill> skillSet;

    public AsGroup(Integer year, Collection<Skill> skillSet) {

        this.year = year;
        this.skillSet = skillSet;
    }

    public AsGroup addSkills(AsGroup asGroupSkills) {
        this.skillSet.addAll(asGroupSkills.skillSet);
        return this;
    }
}

然后你可以用以下方法解決你的問題:

Map<Integer, Optional<com.company.Main.AsGroup>> groupedByYear = workExperienceList.stream()
                .map(workExperience ->
                        new AsGroup(workExperience.getYear(), new HashSet<>(workExperience.getSkill()))
                ).collect(groupingBy((asGroup) -> asGroup.year,
                          reducing((group1, group2) -> (group1.addSkills(group2))))
                );

您可以按如下方式使用它:

groupedByYear.forEach(((year, groupedSkills) -> System.out.println(year + " " + groupedSkills.get().skillSet)));

它打印如下:

2017 [Skill [skill=Skill-1], Skill [skill=Skill-1], Skill [skill=Skill-4], Skill [skill=Skill-2], Skill [skill=Skill-2], Skill [skill=Skill-3]]
2018 [Skill [skill=Skill-1], Skill [skill=Skill-2], Skill [skill=Skill-9]]

轉換List的stream<object> 列表中所有對象的 stream<div id="text_translate"><p> 以下 lambda 表達式采用 HashMap 的值,在其 ArrayList 中獲取對象列表,將所有此類對象添加到另一個 ArrayList,然后在滿足條件時打印每個屬性。</p><p> 這行得通,但我有點沮喪,我不知道如何一步完成,就像不使用兩個 lambda 表達式一樣。</p><pre> Map<Integer, Person> people = new HashMap<Integer, Person>(); ... List<Object> objects = new ArrayList<Object>(); people.values().stream().map(p->p.getObjects()).forEach(p->objects.addAll(p)); //note: can be multiple objects.stream().filter(p->p.getClass().toString().contains("Keyword")).forEach(p->System.out.println(p.display()));</pre><p> 那么有沒有一種方法可以將 go 從第 2 行直接轉到第 5 行,這實際上會將對象列表的 stream 轉換為所有對象本身的 stream?</p></div></object>

[英]Convert stream of List<Object> to stream of all Objects in the List

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

相關問題 將流列表轉換為列表 RxJava。 將列表的可熱觀測數據轉換為單項流,對其進行處理並轉換回列表 轉換列表<List<String> &gt; 流<Stream<String> &gt; Lambda +流將List <A>提取到單個列表 如何將Maps的Stream轉換成單個Map 使用 stream() 將嵌套列表轉換為列表 使用流將列表轉換為另一個列表 轉換List的stream<object> 列表中所有對象的 stream<div id="text_translate"><p> 以下 lambda 表達式采用 HashMap 的值,在其 ArrayList 中獲取對象列表,將所有此類對象添加到另一個 ArrayList,然后在滿足條件時打印每個屬性。</p><p> 這行得通,但我有點沮喪,我不知道如何一步完成,就像不使用兩個 lambda 表達式一樣。</p><pre> Map<Integer, Person> people = new HashMap<Integer, Person>(); ... List<Object> objects = new ArrayList<Object>(); people.values().stream().map(p->p.getObjects()).forEach(p->objects.addAll(p)); //note: can be multiple objects.stream().filter(p->p.getClass().toString().contains("Keyword")).forEach(p->System.out.println(p.display()));</pre><p> 那么有沒有一種方法可以將 go 從第 2 行直接轉到第 5 行,這實際上會將對象列表的 stream 轉換為所有對象本身的 stream?</p></div></object> 通過地圖流過濾並收集到一個列表中? Java 8:將流列表合並為一個 stream
 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM