-1

I have this CasaDeBurrito class:

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;
...
}

and this profesor class: (it should be with one 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));
    }
}

I want to implement a function which gets a Profesor prof, and unifies all the sets of favorites of all prof's friends, sorted by ID, with stream. as a result I want a collection of all favorite CasaDeBurrito restaurants by rating (with favoritesByRating).

for example:

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;
}
Guy Sadoun
  • 427
  • 6
  • 17

2 Answers2

1

You want a a collection of all CasaDeBurrito favorites by friends sorted by name so I'd say a Map<String, List<CasaDeBurrito>> would be what you need, each key i a friend name, and the value is the list of CasaDeBurrito he likes using your favoritesByRating method, all sorted by name (use of 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));
}

If you just want a list of the CasaDeBurrito liked by the friends use flatMap

public List<CasaDeBurrito> favoritesByRating(Profesor p) {
    return p.getFriends().stream()
            .flatMap(prof -> prof.favoritesByRating(0).stream())
            .collect(toList());
}
azro
  • 53,056
  • 7
  • 34
  • 70
  • can I flat the value list of map? I mean to make a list of lists of all the values and then flatten it as they suggest above – Guy Sadoun Nov 25 '19 at 09:15
  • 1
    @GuySadoun this is what the second code do, but all in one, this is same as : p.getFriends().stream().map(prof->prof.favoritesByRating(0)).flatMap(List::stream) – azro Nov 25 '19 at 18:27
0

so I didn't know how to ask correctly but I manage to connect the comments and answers to what I needed. I sort the friends by ID and created a stream of collection as @Alex Faster share in his comment here and flatten the stream as suggested above.

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>

I will edit my question again to make it more clear now.

Guy Sadoun
  • 427
  • 6
  • 17