Difference between map and flatMap in Java 8 Stream

Java doc says
map
Returns a stream consisting of the results of applying the given function to the elements of this stream.
flatMap
Returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. Each mapped stream is
closed
after its contents have been placed into this streamUnable to understand the difference between map and flatMap when should we use map and when flatMap?

Find the difference between Stream map() and flatMap() in Java 8.
1. flatMap() flattens the elements after applying the function whereas map() only apply function on the elements and does not flatten.
flatMap() works as follows.
a. Stream of writers.
{
{"Mohan",
{
{10,"AAA"}, {20,"BBB"}
}
},
{"Sohan",
{
{30,"XXX"}, {15,"ZZZ"}
}
}
}
b. After flatMap(writer -> writer.getBooks().stream()), find the stream of books.
{
{10,"AAA"},
{20,"BBB"},
{30,"XXX"},
{15,"ZZZ"}
}
Here the result has been flattened.
Now map() works as follows.
a. Stream of integer.
{2, 3, 4, 5}
b. After map(i -> i*2), find the stream of integer.
{4 6 8 10}
2. Stream map() and flatMap() both accepts a java 8 Function but Stream map() returns a single value where as flatMap() can return more than one values.
Example of flatMap()
public static void main(String[] args) {
List<Book> books = Arrays.asList(new Book(10, "AAA"), new Book(20, "BBB"));
Writer w1 = new Writer("Mohan", books);
books = Arrays.asList(new Book(30, "XXX"), new Book(15, "ZZZ"));
Writer w2 = new Writer("Sohan", books);
List<Writer> writers = Arrays.asList(w1, w2);
Book book = writers.stream().flatMap(writer -> writer.getBooks().stream())
.max(new BookComparator()).get();
System.out.println("Name:"+book.getName()+", Price:"+ book.getPrice() );
}
http://www.concretepage.com/java/jdk-8/java-8-flatmap-example
Example of map()
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<>();
map.put(111, "Lalkrishna");
map.put(154, "Atal");
map.put(30, "Narendra");
map.put(200, "Amit");
List<User> list = map.entrySet().stream().sorted(Comparator.comparing(e -> e.getKey()))
.map(e -> new User(e.getKey(), e.getValue())).collect(Collectors.toList());
list.forEach(l -> System.out.println("Id: "+ l.getId()+", Name: "+ l.getName()));
}
Find the link
http://www.concretepage.com/java/jdk-8/java-8-stream-map-example