假设你有这样的结构类:
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
个对象。
可能吗?一个级别很简单,但有两个级别我们找不到任何示例或文档。
答案 0 :(得分:15)
猜猜你需要什么:(假设getter可用于Review
和RelReviewImage
)
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());
答案 1 :(得分:2)
我认为你可以在这里获得最易于维护和优雅的代码,而不是尝试单线程。 :)
当我有这些嵌套结构时,我通常为每个级别创建一个新方法。因此,当我编码时,我一次只需要一个级别。
尝试将检查imageId
图像是否存在的部分拉入Predicate
。
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
作为参数,您可以使用相同的方法,通过传递不同的{{1来过滤Review
内的所有不同字段}}
答案 2 :(得分:0)
以下是一些基本想法:
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;
}
}
答案 3 :(得分:0)
要求说您要基于idImage进行过滤,idImage是我们列表ArrayList图像流中的字段
第1步:
images.stream()
.filter(idImage->idImage.equals("I123");
如果找到匹配项,我们的目标将得到满足
第二步:
images.stream()
.filter(idImage->idImage.equals("I123")
.findAny()//this will return Optional<RelReviewImage> object which will be populated if object is found also need not worry about null condition
.isPresent()//this will check if the Optional<RelReviewImage> object was populated
但是我们从哪里得到这些图像流? 它存在于Review类中,因此可以直接说 步骤3
Review myReview-new Review();
myReview.getImages.stream()
.filter(idImage->idImage.equals("I123")
.findAny()
.isPresent()
但是我们要拥有所有listOfReviewObjects 假设我们有ListOfReviewObjects
//Ignore below line of code if not clear,bottomLine is you get list of review objects
List<Review> reviews = IntStream.rangeClosed(0, 10).mapToObj(e->new Review()).collect(Collectors.toList());
第4步
reviews.stream()
.filter("XYZ condition")
.collect(Collectors.toList());
我们的过滤条件是按照步骤2进行的,因此请整理我们拥有的每一件
第5步
reviews.stream()
.filter(review->review.getImages().stream()
.filter(relReviewImage->relReviewImage.getIdImage().intValue()==imageId)
.findAny()
.isPresent())
.collect(Collectors.toList());