【问题标题】:how to unify object's collections from stream of objects如何从对象流中统一对象的集合
【发布时间】:2020-03-19 11:13:53
【问题描述】:

我有这个 CasaDeBurrito 课程:

public class CasaDeBurritoImpl implements OOP.Provided.CasaDeBurrito {

    private Integer id;
    private String name;
    private Integer dist;
    private Set<String> menu;
    private Map<Integer, Integer> ratings;
...
}

还有这个教授类:(应该是一个s)

public class ProfessorImpl implements OOP.Provided.Profesor {

    private Integer id;
    private String name;
    private List<CasaDeBurrito> favorites;
    private Set<Profesor> friends;

    private Comparator<CasaDeBurrito> ratingComparator = (CasaDeBurrito c1, CasaDeBurrito c2) ->
    {
        if (c1.averageRating() == c2.averageRating()) {
            if (c1.distance() == c2.distance()) {
                return Integer.compare(c1.getId(), c2.getId());
            }
            return Integer.compare(c1.distance(), c2.distance());
        }
        return Double.compare(c2.averageRating(), c1.averageRating());
    };

    private Predicate<CasaDeBurrito> isAvgRatingAbove(int rLimit) {
        return c -> c.averageRating() >= rLimit;
    };

    public Collection<CasaDeBurrito> 
    filterAndSortFavorites(Comparator<CasaDeBurrito> comp, Predicate<CasaDeBurrito> p) {
            return favorites.stream().filter(p).sorted(comp).collect(Collectors.toList());
    }

    public Collection<CasaDeBurrito> favoritesByRating(int rLimit) {
            return filterAndSortFavorites(ratingComparator, isAvgRatingAbove(rLimit));
    }
}

我想实现一个函数,它得到一个Profesor prof,并将prof的所有朋友的所有favorites集合,按ID排序,与流。 因此,我想要按评分(使用 favoritesByRating)收集所有最喜欢的 CasaDeBurrito 餐厅。

例如:

public Collection<CasaDeBurrito> favoritesByRating(Profesor p) {

    Stream ret = p.getFriends().stream()
               .<*some Intermediate Operations*>.
               .forEach(y->y.concat(y.favoritesByRating(0))
               .<*some Intermediate Operations*>.
               .collect(toList());
    return ret;
}

【问题讨论】:

标签: java collections java-stream flatten


【解决方案1】:

你想要一个a collection of all CasaDeBurrito favorites by friends sorted by name,所以我会说你需要一个Map&lt;String, List&lt;CasaDeBurrito&gt;&gt;,每个键都是朋友的名字,值是CasaDeBurrito的列表,他喜欢使用你的favoritesByRating方法,所有按名称排序(使用TreeMap

public Map<String, List<CasaDeBurrito>> favoritesByRating(Profesor p) {
    return p.getFriends().stream()
            .collect(toMap(Profesor::getName, prof -> prof.favoritesByRating(0), (i, j) -> i, TreeMap::new));
}

如果您只想要朋友喜欢的CasaDeBurrito 列表,请使用flatMap

public List<CasaDeBurrito> favoritesByRating(Profesor p) {
    return p.getFriends().stream()
            .flatMap(prof -> prof.favoritesByRating(0).stream())
            .collect(toList());
}

【讨论】:

  • 可以把map的值列表放平吗?我的意思是列出所有值的列表,然后按照上面的建议将其展平
  • @GuySadoun 这是第二个代码所做的,但合而为一,这与:p.getFriends().stream().map(prof->prof.favoritesByRating(0)) .flatMap(List::stream)
【解决方案2】:

所以我不知道如何正确提问,但我设法将 cmets 和答案与我需要的内容联系起来。 我按 ID 对朋友进行排序,并创建了一个集合流,@Alex Faster 在他的评论 here 中分享,并按照上面的建议展平流。

return p.getFriends().stream()  //Stream<Profesor>
                .sorted(Comparator.comparingInt(Profesor::getId)) //Stream<Profesor>
                .map(P->P.favoritesByDist(0)) //Stream<Collection<CasaDeBurrito>>
                .flatMap(Collection::stream) //Stream<CasaDeBurrito>
                .distinct()
                .collect(Collectors.toList()); //List<CasaDeBurrito>

我将再次编辑我的问题以使其更清楚。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-08
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    • 2013-05-11
    • 1970-01-01
    相关资源
    最近更新 更多