【问题标题】:Java collectingAndThen R is not convertible to Set<Post>Java collectAndThen R 不能转换为 Set<Post>
【发布时间】:2019-05-25 15:34:32
【问题描述】:

网站上有一些类似的问题,但他们使用的地图会改变类型。我不太明白我在这段代码中做错了什么,我希望有人能纠正我。

代码取自 JPARepository,因此 findAll() 但可以忽略

编辑 - 返回 forEach 不起作用,但我只关心 R 不可转换的错误。为 setPosts 添加签名

boolean canViewHidden = hasAuthority(Permissions.Post.VIEWHIDDEN);
        //findAll should return List<Category>
        return categoryRepository.findAll().forEach(
                //each category has a Set<Post> accessible by getPosts
                category -> category.getPosts().stream()
                    //filtering out the posts that we can't view
                    .filter(post -> canViewHidden || !post.isHidden())

                     //my understanding is filter results in a Stream of Post
                     //however category::setPosts here gives the R is not convertible to Set<Post>                      
                    .collect(Collectors.collectingAndThen(Collectors.toSet(), category::setPosts))
        );

来自 Post.java 的 setPosts 方法

public void setPosts(Set<Post> posts) {
    this.posts = posts;
}

//spring annotation can be ignored
@OneToMany(mappedBy = "category")
private Set<Post> posts;

【问题讨论】:

  • forEach 不返回无效吗?如果它有效,我会感到惊讶。
  • 不管怎样,你能把setPosts的签名贴出来吗?
  • 已编辑,谢谢,你说得对,返回 foreach 不起作用我最初使用的是 Stream.of()...我真的只是关心不可转换的原因

标签: java-8 java-stream


【解决方案1】:

collectingAndThen 期望第二个参数是Function,以允许用户对收集的Collection 应用最后的转换。但是,category::setPosts 不会转换集合,它只是接受一个集合但返回void。那是行不通的。

如果您只想针对每个类别将帖子列表替换为您的流操作描述的子集,您可以执行以下操作:

categoryRepository.findAll().forEach(category -> {
    Set<Post> posts = category.getPosts().stream()
        .filter(post -> canViewHidden || !post.isHidden())
        .collect(Collectors.toSet());
    category.setPosts(posts);
});

【讨论】:

    【解决方案2】:

    我不确定 Post 是什么,所以我改用 String 并过滤长度为 2 的字符串。您应该能够调整它以使用任何具有适当过滤器的类。

    这是我想出的。你说你想返回一个列表,所以我这样做而不是设置。请注意,您不需要进行第二次转换,因此不需要 collectingAndThen

          List<Category> categoryRepository = new ArrayList<>();
    
          categoryRepository.add(
                new Category(Set.of("A", "B", "C", "DE", "FG", "ABC")));
          categoryRepository.add(new Category(
                Set.of("AAAA", "BBBB", "CC", "DDDE", "FFFG", "ABC", "12")));
          categoryRepository.add(
                new Category(Set.of("ARS", "AB", "CCC", "RE", "GG", "ABC")));
    
          List<String> list = categoryRepository.stream().flatMap(
                a -> a.getPosts().stream()).filter(a -> a.length() == 2).collect(
                      Collectors.toList());
          System.out.println(list);
       }
    
    }
    
    class Category {
       private Set<String> posts;
    
       public Category(Set<String> posts) {
          this.posts = posts;
       }
    
       public Set<String> getPosts() {
          return posts;
       }
    }
    
    • List 被转换为 Category 的 stream()
    • 然后每个 Category 通过 getPosts() 检索 Set,并被 flatMapped 到一个公共的字符串流(这些将是您的帖子)。
    • 然后每个字符串(帖子)被过滤并放置在一个列表或集合中 您的选择并返回。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-24
      • 1970-01-01
      • 2011-08-22
      • 1970-01-01
      • 2011-01-15
      • 1970-01-01
      • 1970-01-01
      • 2021-10-15
      相关资源
      最近更新 更多