Skip to content

Instantly share code, notes, and snippets.

@forax
Created January 29, 2014 09:51
Show Gist options
  • Save forax/8684788 to your computer and use it in GitHub Desktop.
Save forax/8684788 to your computer and use it in GitHub Desktop.
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);
}
}
@forax
Copy link
Author

forax commented Jan 29, 2014

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

@nremond
Copy link

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?

@MarcosAntonioPS
Copy link

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.

@forax
Copy link
Author

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

@MarcosAntonioPS
Copy link

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
Copy link

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