2014-12-01 187 views
11

假設你有結構類這樣的:的Java 8個嵌套流

public class Review{ 
    private Integer idReview; 
    private String description; 
    private ArrayList<RelReviewImage> images; 
} 

public class RelReviewImage{ 
    private Integer idRelReviewImage; 
    private Integer idImage; 
    private String name; 
} 

利用Java 8和Stream小號,我們希望做一個過濾器爲idImage,並返回Review對象。
可能嗎?一個級別很容易,但2級我們找不到任何示例或文檔。

+1

你的問題不清楚 - 您可以顯示的代碼的例子有輸入和預期的輸出? – assylias 2014-12-01 20:09:46

回答

12

猜你需要什麼:(假設干將可供ReviewRelReviewImage

List<Review> originalReviews = ... 

List<Review> result = originalReviews.stream() 
    .filter(review -> review.getImages().stream() //Nested streams. Assume getImages() never null, but empty 
          .anyMatch(image -> image.getIdImage() == 123)) //'2 level' here 
    .collect(Collectors.toList()); 
2

我想你可以通過不嘗試了一個班輪在這裏獲得最大的維護和優雅的代碼。 :)

當我有這些嵌套結構時,我通常會爲創建一個每個級別的新方法。所以,當我編碼時,我一次只能在腦海中一個層次。

嘗試將檢查是否存在imageId的圖像的部分拉入Predicate

A Predicate這裏是一個Function需要你的Review並返回一個Boolean可以過濾。

public List<Review> filterReviews(){ 
    Integer idImage = 1; 
    List<Review> reviews = new ArrayList<>(); 
    ... 
    List<Review> result = reviews.stream() 
      .filter(hasImage(idImage)) 
      .collect(Collectors.toList()); 

    return result; 
} 

private Predicate<Review> hasImage(final Integer idImage){ 
    return review -> review.images.stream() 
      .anyMatch(image -> Objects.equals(image.idImage, idImage)); 
} 

普羅蒂普

如果filterReviews - 方法採取了Predicate作爲參數,你可以用同樣的方法,在所有不同領域的過濾器內部Review,通過傳遞不同Predicates

+0

我認爲將'hasImage'方法添加到'Review'類中會更好,它只是返回普通的舊'boolean'。然後你可以'.filter(Review :: hasImage)'。這也將封裝「圖像」存儲。假設稍後您將'List 圖像'更改爲'Map id2image'。然後'hasImage'將被縮減爲'return id2image.containsKey(idImage);' – 2015-08-30 09:36:12

1

下面是一些基本的理念:

public static void main(String[] args) { 
    // TODO Auto-generated method stub 

    List<Review> reviews = new ArrayList<>(); 
    for(int i = 0; i < 50; i++) { 
     List<RelReviewImage> revImg = new ArrayList<>(); 
     for(int j = 0; j < 5; j++) { 
      revImg.add(new RelReviewImage(j, j, "img_"+j)); 
     } 
     reviews.add(new Review(i, "rev" + i, revImg)); 
    } 

    List<Review> result = reviews.stream().filter(r -> r.getImages().stream().anyMatch(i -> i.getIdImage().intValue() < 2)).collect(Collectors.toList()); 

} 

public class Review { 
    private Integer idReview; 
    private String description; 
    private List<RelReviewImage> images; 

    public Review(Integer id, String desc, List<RelReviewImage> img) { 
     super(); 
     this.idReview = id; 
     this.description = desc; 
     this.images = img; 
    } 

    public Integer getIdReview() { 
     return idReview; 
    } 

    public void setIdReview(Integer idReview) { 
     this.idReview = idReview; 
    } 

    public String getDescription() { 
     return description; 
    } 

    public void setDescription(String description) { 
     this.description = description; 
    } 

    public List<RelReviewImage> getImages() { 
     return images; 
    } 

    public void setImages(List<RelReviewImage> images) { 
     this.images = images; 
    } 
} 

public class RelReviewImage { 
    private Integer idRelReviewImage; 
    private Integer idImage; 
    private String name; 

    public RelReviewImage(Integer id, Integer id_img, String name) { 
     super(); 
     this.idRelReviewImage = id; 
     this.idImage = id_img; 
     this.name = name; 
    } 

    public Integer getIdRelReviewImage() { 
     return idRelReviewImage; 
    } 

    public void setIdRelReviewImage(Integer idRelReviewImage) { 
     this.idRelReviewImage = idRelReviewImage; 
    } 

    public Integer getIdImage() { 
     return idImage; 
    } 

    public void setIdImage(Integer idImage) { 
     this.idImage = idImage; 
    } 

    public String getName() { 
     return name; 
    } 

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

儘管這段代碼可能會回答這個問題,但提供關於如何解決問題和/或爲什麼解決問題的額外上下文會提高答案的長期價值。 – 2017-01-12 13:04:36