stream.collect(Collectors.groupingBy(function))
Map<String, List<String>> groups = Stream.of(words) .collect(Collectors.groupingBy( w -> w.substring(0, 1))); // The function for extracting the keys
groups.get("a") is a list of all words starting with aCollectors.groupingByMap<String, Set<String>> groupOfSets = Stream.of(words)
.collect(Collectors.groupingBy(
w -> w.substring(0, 1), // The function for extracting the keys
Collectors.toSet())); // The group collectorgroupingBy collector collects the stream into groupstoSet collector collects each group int a setCollectors.counting() to count the group values
Map<String, Long> groupCounts = Stream.of(words)
.collect(Collectors.groupingBy(
w -> w.substring(0, 1),
Collectors.counting()));groupCounts.get("a") is the number of words that start with an asummingInt, summingDouble, summingLong:
Map<String, Long> groupSum = countries.collect(
Collectors.groupingBy(
c -> c.getContinent(), // The function for extracting the keys
Collectors.summingLong(
c -> c.getPopulation()))); // The function for getting the summandsgroupSum.get("Asia") is the total population of Asian countriesCollectors methods averagingInt, averagingDouble, averagingLongwork just like summingXxxOption)Map<String, Double> groupAverages = Stream.of(words)
.collect(Collectors.groupingBy(
w -> w.substring(0, 1),
Collectors.averagingInt(String::length)));maxBy, minBy use a comparison function and return
Optional results:
Map<String, Optional<String>> groupLongest = Stream.of(words)
.collect(
Collectors.groupingBy(
w -> w.substring(0, 1), // The function for extracting the keys
Collectors.maxBy(
(v, w) -> v.length() - w.length()))); // The comparator functionName: Five Easy Pieces Year: 1970 Directed by: Bob Rafelson Produced by: Bob Rafelson, Richard Wechsler, Harold Schneider Actors: Jack Nicholson, Karen Black, Billy Green Bush, more...
public static List<Movie> readMovies(String url) throws IOException
{
List<Movie> movies = new ArrayList<>();
try (Scanner in = new Scanner(new URL(url).openStream()))
{
while (in.hasNextLine())
{
String nameLine = in.nextLine();
String yearLine = in.nextLine();
String directorsLine = in.nextLine();
String producersLine = in.nextLine();
String actorsLine = in.nextLine();
movies.add(new Movie(getString(nameLine),
Integer.parseInt(getString(yearLine)),
getList(directorsLine),
getList(producersLine),
getList(actorsLine)));
}
}
return movies;
}
Here, getString is a helper method that strips off the field header, and getList is a helper that
breaks up a comma-separated list:
private static String getString(String line)
{
int colon = line.indexOf(":");
return line.substring(colon + 1).trim();
}
private static List<String> getList(String line)
{
return Stream.of(getString(line).split(", "))
.collect(Collectors.toList());
}
List<Movie> movieList = readMovies("http://horstmann.com/heig-vd/spring2015/poo/unit5/movies.txt");
Stream<Movie> movies = movieList.stream();List<String> result1 = movieList.stream()
.map(m -> m.getTitle())
.filter(t -> t.startsWith("X"))
.collect(Collectors.toList());groupingBy with a secondary collector:
Map<String, Long> firstLetters = movieList.stream()
.collect(Collectors.groupingBy(
m -> m.getTitle().substring(0, 1),
Collectors.counting()));
How many movies start with the letter T?movieList.stream()
.filter(m -> m.getTitle().startsWith("The "))
.count();Map<String, List<Movie>> moviesByDirector = movieList.stream()
.filter(m -> m.getDirectors().size() > 0)
.collect(Collectors.groupingBy(
m -> m.getDirectors().get(0)));
This map associates all directors with a list of the movies that they directed. Unfortunately,
that’s a large map. How many entries does it have?
String mostProlificDirector = Collections.max( moviesByDirector.entrySet(), Comparator.comparing(e -> e.getValue().size())).getKey();Who is this director? Never heard of him? Google his name!
List<String> titles = moviesByDirector.get(mostProlificDirector) .stream() .map(m -> m.getTitle()) .collect(Collectors.toList());Which of these would you like to see first?
parallelStream on a collection:
Stream<String> parallelWords = words.parallelStream();
parallel on any stream:
Stream<String> parallelWords = Stream.of(wordArray).parallel();
long result = wordStream.parallel() .filter(w -> w.length() > 10) .count();

int[] shortWords = new int[12];
words.parallelStream().forEach(
s -> {
if (s.length() < 12)
shortWords[s.length()]++;
// Error—race condition!
});
Map<Integer, Long> shortWordCounts =
words.parallelStream()
.filter(s -> s.length() < 12)
.collect(Collectors.groupingBy(
String::length,
Collectors.counting()));findAny instead of findFirst if you don't care about orderingunordered to speed up limit or distinct:
Stream<String> sample = words.parallelStream().unordered().limit(n);
groupingByConcurrent to speed up grouping if you don't care about the order in which the values are processed
Map<Integer, Long> wordCounts =
words.parallelStream()
.collect(
Collectors.groupingByConcurrent(
String::length,
Collectors.counting()));Unit5 project, make a new class Exercise2 with this code. Run the code. What do you get?System.out.println("Total: "
+ shortWordCounts.values().stream().mapToLong(n -> n).sum());Exercise3. To measure the execution time of an arbitrary code snippet, add this method:
public static <T> void time(Callable<T> c)
{
Instant start = Instant.now();
try
{
T result = c.call();
System.out.println(result);
}
catch (Exception e)
{
System.out.println(e);
}
long millis = Duration.between(start, Instant.now()).toMillis();
System.out.printf("Elapsed time: %d milliseconds\n", millis);
}
BigInteger numbers:
BigInteger start = BigInteger.valueOf(2).pow(267); int length = 100000; // If you have a fast computer, increase this value List<BigInteger> bs = IntStream.range(1, length) .mapToObj(i -> BigInteger.valueOf(i).add(start)) .collect(Collectors.toList());
bs into a stream and find the prime numbers that contain the sequence 666:
bs.stream()
.filter(b -> b.isProbablePrime(100))
.filter(b -> b.toString().contains("666"))
.count()time:
time(() -> bs.stream()...count());
length to 200000 and try again.)time command and make the stream parallel:
time(() -> bs.stream().parallel()...count());
count to findAny on both the sequential and parallel streams. What are the timing results? Why?Exercise4 and copy the time method from Exercise 3.Path, yielding a pair of the path and the file:
public static Pair<Path, String> read(Path p)
{
try
{
return Pair.of(p, new String(Files.readAllBytes(p)));
}
catch (IOException e)
{
return Pair.of(p, "");
}
}
Add this method that finds the longest word in a string that holds the contents of a file. We split along non-letters (regex \PL+), and the rest is standard stream stuff.
public static String longestWord(String contents)
{
return Stream.of(contents.split("\\PL+"))
.max(Comparator.comparing(String::length))
.orElse("");
}
String zippath = "/opt/jdk1.8.0/src.zip";
FileSystem zipfs = FileSystems.newFileSystem(Paths.get(zippath), null);
try (Stream<Path> entries = Files.walk(zipfs.getPath("/")))
{
...
}
However, you'll need to change the zippath variable to point where your src.zip is located. In Windows, it's in c:\Program Files\Java\jdk1.8.0_xx. (Remember to use double backslashes in strings.) In Mac OS X, it's in something like /Library/Java/JavaVirtualMachines/jdk1.8.0_xx.jdk/Contents/Home. In Linux, if you installed the JDK yourself, you know where it is. If you use openjdk-8 on Ubuntu, you need to sudo apt-get install openjdk-8-src, and look in /usr/lib/jvm/openjdk-8.main as throws IOException. Add
time(() -> entries.count());where the
... are. Run the program. You should get about 8220 files..count() and add these stream operations:
.filter(Files::isRegularFile) .map(Exercise4::read) .map(p -> Pair.of(p.first(), longestWord(p.second()))) .sorted(Comparator.comparing(p -> -p.second().length())) .limit(10) .collect(Collectors.toList())What do they do? (In plain English or French, what's the high-level idea?)
makeInfoOnlyServantCacheLocalClientRequestDispatcherFactory?