what is the actual difference between map() and flatMap()?

hi guys. can smb help me out with stream().map() and stream().flatmap? In the google i saw that flatmap flattens smth. What does it even mean? Can smb explain? Thanks alot
44 Replies
JavaBot
JavaBot12mo ago
This post has been reserved for your question.
Hey @bambyzas! Please use /close or the Close Post button above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically closed after 300 minutes of inactivity.
TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here.
Kyo-chan
Kyo-chan12mo ago
To map() and flatMap(), you pass converters. Converting each item of the stream to something else, making the original stream a new stream where all is converted. But with flatMap(), the converter has to convert to a stream of something. If you gave the same converter to just map(), that would result in a stream of streams of stuff, which isn't useful. flatMap() applies the converter given, but flattens the result. Instead of giving out a stream of streams of stuff, it gives out just a stream of stuff.
0x150
0x15012mo ago
-> with flatMap, one element becomes many eg if you have a stream of “ab”, “cd” flatMapping it with a function that turns the string into their individual characters and returns a stream of them returns in the stream “a”, “b”, “c”, “d”
tjoener
tjoener12mo ago
Yes, but to be more precise, 0 and 1 are also perfectly fine
bambyzas
bambyzasOP12mo ago
can u guys give me an example? if i have List<Vegetables> and i do flatmap on it. what would i get?
tjoener
tjoener12mo ago
Well does a vegetable itself contain a list of some kind?
bambyzas
bambyzasOP12mo ago
no. Vegetable is just a pojo
tjoener
tjoener12mo ago
yeah, flatmap isn't really useful then Lets say you have a list of users, and each user has a list of emails, then you can use flatmap eg: users.stream().flatMap(user -> user.getEmails().stream()).collect(Collectors.toList()) This will give you a list of all users' emails
bambyzas
bambyzasOP12mo ago
ok i did some improvements. lets say i ahve such case:
Vegetable apple1 = new Vegetable(1, "apple1", 1);
Vegetable pear1 = new Vegetable(11, "pear1", 11);
Vegetable egg1 = new Vegetable(111, "egg1", 111);

Farmer farmer1 = new Farmer();
farmer1.setFirstName("Name1");
farmer1.setId(1);
farmer1.setLicense("license1");
farmer1.setLastName("LastName1");
farmer1.setVegetables(List.of(apple1,pear1,egg1);

Vegetable apple2 = new Vegetable(2, "apple2", 2);
Vegetable pear2 = new Vegetable(22, "pear2", 22);
Vegetable egg2 = new Vegetable(222, "egg2", 222);

Farmer farmer2 = new Farmer();
farmer2.setFirstName("Name2");
farmer2.setId(2);
farmer2.setLicense("license2");
farmer2.setLastName("LastName2");
farmer2.setVegetables(List.of(apple2, pear2, egg2));

List<Farmer> farmerList = new ArrayList<>();
farmerList.add(farmer1);
farmerList.add(farmer2);

//List<String> farmerNames = farmerList.stream().map(farmer -> farmer.getFirstName()).collect(Collectors.toList());

farmerList.stream().flatMap(farmer -> farmer.getVegetables(
Vegetable apple1 = new Vegetable(1, "apple1", 1);
Vegetable pear1 = new Vegetable(11, "pear1", 11);
Vegetable egg1 = new Vegetable(111, "egg1", 111);

Farmer farmer1 = new Farmer();
farmer1.setFirstName("Name1");
farmer1.setId(1);
farmer1.setLicense("license1");
farmer1.setLastName("LastName1");
farmer1.setVegetables(List.of(apple1,pear1,egg1);

Vegetable apple2 = new Vegetable(2, "apple2", 2);
Vegetable pear2 = new Vegetable(22, "pear2", 22);
Vegetable egg2 = new Vegetable(222, "egg2", 222);

Farmer farmer2 = new Farmer();
farmer2.setFirstName("Name2");
farmer2.setId(2);
farmer2.setLicense("license2");
farmer2.setLastName("LastName2");
farmer2.setVegetables(List.of(apple2, pear2, egg2));

List<Farmer> farmerList = new ArrayList<>();
farmerList.add(farmer1);
farmerList.add(farmer2);

//List<String> farmerNames = farmerList.stream().map(farmer -> farmer.getFirstName()).collect(Collectors.toList());

farmerList.stream().flatMap(farmer -> farmer.getVegetables(
so now i can use flatmap, right? bc i have a list of lists?
tjoener
tjoener12mo ago
yes
bambyzas
bambyzasOP12mo ago
ok. thanks. but i dont understand what im doing wrong here farmerList.stream().flatMap(farmer -> farmer.getVegetables());
JavaBot
JavaBot12mo ago
If you are finished with your post, please close it. If you are not, please ignore this message. Note that you will not be able to send further messages here after this post have been closed but you will be able to create new posts.
tjoener
tjoener12mo ago
check what flatmap wants It wants a function that returns a stream a collection (or a list) is not a stream
bambyzas
bambyzasOP12mo ago
how do u know? <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
tjoener
tjoener12mo ago
? extends Stream
bambyzas
bambyzasOP12mo ago
doesnt it mean that Function takes two things? wildcard extending a type, and wildcard extending a stream?(idk what that even means)
tjoener
tjoener12mo ago
No Function doesn't change, one return value with one parameter Don't worry about the ? extends or ? super too much Just ignore them for now
bambyzas
bambyzasOP12mo ago
ok. so i have to provide a mapper for flatmap function. And what is the data type of the mapper? that whole Function<... things is very confusing to read and understand
tjoener
tjoener12mo ago
If you ignore the ? super and ? extends, it's basically Function<T, Stream<R>> That should be understandable
bambyzas
bambyzasOP12mo ago
not very clearly tbh. i see that for this interface, if i want to write a lambda (for example) i need to comply to apply method
No description
bambyzas
bambyzasOP12mo ago
but i dont understand how to comply to Function<T, Stream<R>>?
tjoener
tjoener12mo ago
So basically, the T here, becomes the T from the flatmap parameter, the R becomes the Stream<R> from the flatmap parameter I think you need some good generics/lambda/stream tutorials, becuase you asked the same questiosn yesterday about map
bambyzas
bambyzasOP12mo ago
but i know how lambdas and generics work. and i can write needed lambda for map. but flatmap is a little bit more difficult
tjoener
tjoener12mo ago
Well, I'm doubtful about the generics part, because that's what you just asked 🙂
bambyzas
bambyzasOP12mo ago
generics are used when u want ur method to be able to accept/return any type
public class Generic<T> {
T object;

public void createList(){
List<T> genericList = new ArrayList<T>();
genericList.add(object);
System.out.println("my list is: "+genericList.get(0));
}
}

public static void main(String[] args) {
Generic generic = new Generic("AAA");
generic.createList();
}
public class Generic<T> {
T object;

public void createList(){
List<T> genericList = new ArrayList<T>();
genericList.add(object);
System.out.println("my list is: "+genericList.get(0));
}
}

public static void main(String[] args) {
Generic generic = new Generic("AAA");
generic.createList();
}
tjoener
tjoener12mo ago
Yeah but the whole ? super ? extends is a big part of generics Basically what those mean: ? super means that whatever you're presenting needs to be that type, or any parent of it ? extends means that whatever you're presenting needs to be that type, or any subtype of it
bambyzas
bambyzasOP12mo ago
upper and lower bounds correct
tjoener
tjoener12mo ago
See, you get it 🙂
bambyzas
bambyzasOP12mo ago
not really. i cant put everything together into one place
0x150
0x15012mo ago
basically: ? super something means that the generic type accepts any parent class of something, eg with something being String, the generic bound ? super String would accept either String itself, or CharSequence for example. Read: ? super X means "i can assign a value with type X to a variable having that generic type" ? extends something means that the generic type accepts any child class or something, so in the exact other direction. ? extends X means "i can assign a value of that type to a variable of type X"
bambyzas
bambyzasOP12mo ago
i have theoretical knowledge, but cant even write a lambda that complies to the needed functional interface
tjoener
tjoener12mo ago
In flatMap they do that so that if you have a method that takes a charSequence as a parameter, I can apply that on a stream of strings, because a String is a CharSequence That's the ? super And the return value needs to be at least a Stream, and the types of that stream need to be at least what I want the flatMap operation to return If I want it to return a Number, I can pass in a method that returns Integer, because Integer extends Number That's the ? extends
bambyzas
bambyzasOP12mo ago
if i use map, i ctrl-click on it, and see this: <R> Stream<R> map(Function<? super T, ? extends R> mapper); and it basically means, that i need to provide a mapper. its type is Function that operates on two types. then i ctrl-click on function, and see R apply(T t);. so it means that my lambda for .stream().map() has to be smth like .map(farmer->farmer.getName()). but if i do .stream.flatMap() now im stuck and cant write lambda in a similar manner. i ctrl-click on flatMap and i get <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);. so it means that mapper types is a Function that operates on datatype and a stream. then again i ctr-click on Function and see the same R apply (T t). and thats it. idk what to do next, because for mapper i need a Function with 2 args, and here i see that it can actually take only one.
tjoener
tjoener12mo ago
Where's the second arg?
0x150
0x15012mo ago
the function args are the exact same now your function accepts anything above T, and returns a stream of anything below R same thing
Phloof_boll
Phloof_boll12mo ago
So basically, the T here, becomes the T from the flatmap parameter, the R becomes the Stream<R> from the flatmap parameter
tjoener
tjoener12mo ago
What I said here basically
bambyzas
bambyzasOP12mo ago
this would be the logic?
No description
0x150
0x15012mo ago
yes
bambyzas
bambyzasOP12mo ago
ok, but whose stream is it? where do i get it?
0x150
0x15012mo ago
you make it you make a new stream consisting of the elements you want to put into the stream you convert one element to a stream of other elements, which are then "appended" to the current stream or rather, the element you get as an argument is replaced with the elements in the stream you returned for that element
tjoener
tjoener12mo ago
Collection and Optional have .stream() Or you could roll your own
JavaBot
JavaBot12mo ago
💤 Post marked as dormant
This post has been inactive for over 300 minutes, thus, it has been archived. If your question was not answered yet, feel free to re-open this post or create a new one. In case your post is not getting any attention, you can try to use /help ping. Warning: abusing this will result in moderative actions taken against you.
Want results from more Discord servers?
Add your server