Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.Temporal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
public class HeightIn8 {
static class Person {
private final String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return name + ' ' + Integer.toHexString(super.hashCode());
}
}
public static void main(String[] args) throws IOException {
// 1
List<String> list = Arrays.asList(args);
list.sort((s1, s2) -> s1.compareToIgnoreCase(s2));
list.sort(String::compareToIgnoreCase);
// 2
/*Iterator<String> it = list.iterator();
while(it.hasNext()) {
String s = it.next();
if (s.length() %2 == 0) {
it.remove();
}
}*/
list.removeIf(s -> s.length() %2 == 0);
// 3
Map<String, Long> map = new HashMap<>();
for(String s: args) {
map.put(s, 1 + map.getOrDefault(s, 0L));
}
// 4
List<Person> people = Arrays.asList(new Person("Paul"), new Person("John"), new Person("Paul"));
Map<String, List<Person>> byNameMap = new HashMap<>();
for(Person person: people) {
byNameMap.computeIfAbsent(person.getName(), name -> new ArrayList<>()).add(person);
}
// 5
//Map<String, List<Person>> byNameMap = ...
byNameMap.forEach((name, persons) -> {
System.out.println(name + ' ' + persons);
});
// 6
Map<String, List<Person>> byNameMap2 =
people.stream().collect(Collectors.groupingBy(Person::getName));
System.out.println(byNameMap2);
// 7
Path dictionnary = Paths.get("dict.txt");
Map<String, Long> histoMap =
Files.lines(dictionnary)
.flatMap(line -> Arrays.stream(line.split(" ")))
.collect(Collectors.groupingBy(Function.identity(),
Collectors.counting()));
System.out.println(histoMap);
// 8
List<Temporal> temporals = Arrays.asList(LocalDate.now(), LocalDateTime.now());
temporals.stream().map(temporal -> temporal.query(DayOfWeek::from)).forEach(System.out::println);
}
}

Hi Rémi

Could it be possible to add a rss/atom feed to your blog ?

Thomas

Yes, I also would like a rss/atom feed to this blog.

Owner

forax commented Jan 29, 2014

There is one: try http://forax.github.io/rss.xml :)

nremond commented Feb 1, 2014

Isn't it awkward to have to write Arrays.asList(2,3,1).sort(null) to have this list sorted using the natural order? I don't see why there isn't a List.sort() method?

Agreed. There should exist a 'List.sort()' method. And also, passing a null value to the method 'List.sort(Comparator<? super E> c)' should result in a NPE error, as this is more intuitive.

Owner

forax commented Feb 3, 2014

List.sort must be a drop in replacement of Collections.sort and Collections.sort allows the comparator to be null [1].

[1] http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#sort%28java.util.List,%20java.util.Comparator%29

Ok, from this point of view it makes sense because it is consistent with the Collections.sort method. So it seems here that the main reason things are the way they are regarding this particular issue only boils down to consistency with an older api, and readability and intuition are sacrificed because of this. Either in the Collections class or in the List interface a null value just doesn't seem the right way to indicate that a list should be sorted by the natural order of its elements. It just seems like a hack or some kind of workaround.

jnizet commented Feb 5, 2014

Great post. I noticed two bugs in your snippets:

for(Person person: people) {
    byNameMap.getOrDefault(person.getName(), new ArrayList<>()).add(person);
}

should be

for(Person person: people) {
    List<Person> persons = byNameMap.getOrDefault(person.getName(), new ArrayList<>());
    persons.add(person);
    byNameMap.put(persons);
}

Otherwise you would end up with an empty map, if I'm not mistaken, since getOrDefault() doesn't put back the default value in the map automatically like computeIfAbsent() does.

And

for(Map.Entry<String, List<Person>> entry: byNameMap.entrySet()) {
    System.out.println(name + ' ' + persons);
}

should of course be

for(Map.Entry<String, List<Person>> entry: byNameMap.entrySet()) {
    System.out.println(entry.getKey() + ' ' + entry.getValue());
}

which, BTW, makes it much less readable than the Java 8 version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment