2017-09-25 89 views
-1

希望有人會已經解決了這個,嵌套集合塊迭代和範圍在Lambda表達式

對象結構我有類似

主要對象一個對象結構是學生,學生得到了一些信件

public class LetterRange { 
    private Date letterStartDate; 
    private Date letterEndDate; 

    public Date getLetterStartDate() { 
     return letterStartDate; 
    } 

    public void setLetterStartDate(Date letterStartDate) { 
     this.letterStartDate = letterStartDate; 
    } 

    public Date getLetterEndDate() { 
     return letterEndDate; 
    } 

    public void setLetterEndDate(Date letterEndDate) { 
     this.letterEndDate = letterEndDate; 
    } 
} 

public class Letters { 
    private String letterName; 
    private Set<LetterRange> letterRangeSet; 

    public String getLetterName() { 
     return letterName; 
    } 

    public void setLetterName(String letterName) { 
     this.letterName = letterName; 
    } 

    public Set<LetterRange> getLetterRangeSet() { 
     return letterRangeSet; 
    } 

    public void setLetterRangeSet(Set<LetterRange> letterRangeSet) { 
     this.letterRangeSet = letterRangeSet; 
    } 
} 

public class Student { 
    private String name; 
    Set<Letters> lettersSet; 

    public String getName() { 
     return name; 
    } 

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

    public Set<Letters> getLettersSet() { 
     return lettersSet; 
    } 

    public void setLettersSet(Set<Letters> lettersSet) { 
     this.lettersSet = lettersSet; 
    } 
} 
public class StudentRunner { 
    public static void main(String args[]){ 
     List<Student> studentList= new ArrayList<>(); 
     Student one= new Student(); 
     one.setName("John"); 
     Letters johnLetter1= new Letters(); 
     johnLetter1.setLetterName("Kudos1"); 
     LetterRange johnLetter1Range= new LetterRange(); 
     johnLetter1Range.setLetterStartDate(new Date()); 
     johnLetter1Range.setLetterEndDate(new Date()); 
     LetterRange johnLetter2Range= new LetterRange(); 
     johnLetter1Range.setLetterStartDate(DateTime.now().plus(10).toDate()); 
     johnLetter1Range.setLetterEndDate(DateTime.now().plus(10).toDate()); 
     johnLetter1.setLetterRangeSet(new HashSet<LetterRange>(){{add(johnLetter1Range); add(johnLetter2Range);}}); 
     one.setLettersSet(new HashSet<Letters>(){{add(johnLetter1);}}); 
     studentList.add(one); 
     studentList.forEach(student -> student.getLettersSet().stream().flatMap(letters -> letters.getLetterRangeSet())); 
    } 
} 

我堅持在哪裏試圖讓lambda返回給我給所有學生的所有letterRanges。我知道我們可以迭代舊的方式,但我試圖看看是否有一個lambda可以幫助我。 TIA。

+0

更改僞一點,謝謝 –

+0

讓我複製粘貼代碼,。少數。更新它。 –

+0

你真的複製粘貼這段代碼嗎?代碼中有很多明顯的錯誤! (例如,「類」而不是「類」) –

回答

6

你需要的是2個平面地圖:

Set<LetterRange> rangeOfLetters = studentList.stream() 
     .flatMap(x -> x.letterSet.stream()) 
     .flatMap(x -> x.letterRanges.stream()) 
     .collect(Collectors.toSet()); 

平面地圖操作可以把這個:

[[1, 2, 3], [4, 5, 6], [7, 8, 9]] 

成這樣:

[1, 2, 3, 4, 5, 6, 7, 8, 9] 

你的數據結構是這樣的:

[ 
    < 
     {LetterRange, LetterRange, LetterRange}, 
     {LetterRange, LetterRange, LetterRange}, 
     {LetterRange, LetterRange, LetterRange} 
    >, 
    < 
     {LetterRange, LetterRange, LetterRange}, 
     {LetterRange, LetterRange, LetterRange}, 
     {LetterRange, LetterRange, LetterRange} 
    >, 
    < 
     {LetterRange, LetterRange, LetterRange}, 
     {LetterRange, LetterRange, LetterRange}, 
     {LetterRange, LetterRange, LetterRange} 
    > 
] 

[]代表最外面的一組。 <>代表學生對象,而{}代表字母對象。

第一平面地圖的地圖轉動數據轉換成這樣的:

[ 
     {LetterRange, LetterRange, LetterRange}, 
     {LetterRange, LetterRange, LetterRange}, 
     {LetterRange, LetterRange, LetterRange}, 
     {LetterRange, LetterRange, LetterRange}, 
     {LetterRange, LetterRange, LetterRange}, 
     {LetterRange, LetterRange, LetterRange}, 
     {LetterRange, LetterRange, LetterRange}, 
     {LetterRange, LetterRange, LetterRange}, 
     {LetterRange, LetterRange, LetterRange} 
    ] 

和第二扁平地圖接通數據轉換成:

[ 
    LetterRange, LetterRange, LetterRange, 
    LetterRange, LetterRange, LetterRange, 
    LetterRange, LetterRange, LetterRange, 
    LetterRange, LetterRange, LetterRange, 
    LetterRange, LetterRange, LetterRange, 
    LetterRange, LetterRange, LetterRange, 
    LetterRange, LetterRange, LetterRange, 
    LetterRange, LetterRange, LetterRange, 
    LetterRange, LetterRange, LetterRange 
] 
+0

毆打39秒 –

4

解決這方面的一個方法是使用中間變量和看看你在每個階段得到什麼。

Stream<Student> studentStream = studentList.stream(); 

...是一個好的開始。你可以爲自己制定studentStream的類型,這很好。但是你的IDE會告訴你它是否是錯誤的 - 你甚至可以讓IDE爲你輸入正確的類型。

你知道你需要flatMap,因爲你知道你正在展開一個嵌套結構。你傳遞給flatMap功能都要消耗Student並返回一個Stream<?>,所以你的選擇是有限的:

Stream<Letters> lettersStream = studentStream.flatMap(
    stu -> stu.getLettersSet().stream()); 

獲取從Stream<Letters>更接近你的目標基本上是思想的火車一樣像以前那樣:

Stream<LetterRange> letterRangeStream = lettersStream.flatMap(
    ls -> ls.getLetterRangeSet().stream()); 

...現在你有你想要的東西;你只需要收集成一個List

List<LetterRange> letterRanges = letterRangeStream.collect(Collectors.toList()); 

你可以選擇離開它這樣:

Stream<Student> studentStream = studentList.stream(); 
    Stream<Letters> lettersStream = studentStream.flatMap(
      stu -> stu.getLettersSet().stream()); 
    Stream<LetterRange> letterRangeStream = lettersStream.flatMap(
      ls -> ls.getLetterRangeSet().stream()); 
    List<LetterRange> letterRanges = letterRangeStream.collect(Collectors.toList()); 

...這是很好的 - 的JRE會優化掉中間變量反正。但是,如果你願意,你可以內聯它們(手工或用IDE的「內聯變量」重構工具):

List<LetterRange> letterRanges = studentList.stream() 
    .flatMap(stu -> stu.getLettersSet().stream()) 
    .flatMap(ls -> ls.getLetterRangeSet().stream()) 
    .collect(Collectors.toList()); 
+0

我錯過了做扁平地圖的部分,使它更加平坦。我試圖重新調整內聯代碼以保持簡單。謝謝! –