Default Method
Using Optional
- as return value, field (Optional
Optional.ofNullable/orElse(T value)/orElseThrow
ifPresent(Consumer consumer)/orElseThrow(XException::new)
Map + ConcurrentHashMap
ConcurrentHashMap<String, Integer> wordMap = new ConcurrentHashMap<String, Integer>(16, 0.9f, 1);
targets.computeIfAbsent(ticket[0], k -> new PriorityQueue()).add(ticket[1]);
counters.computeIfAbsent(name, k -> new AtomicInteger()).incrementAndGet();
map.computeIfAbsent("key", k -> new LongAdder()).increment();
map.putIfAbsent(sum, i);
Instead of:
if (!map.containsKey(sum)) {
map.put(sum, i);
}
map.getOrDefault(key, defaultValue)
wordMap.merge(word, occurrence, (key, value) -> wordMap.getOrDefault(key, 0) + value);
wordMap.reduceValues(1,(count1,count2) -> count1+count2);
concurrentHashMap.search(threshold, (k, v) -> v > 1000 ? k : null);
Lambda
iterable.forEach(x -> x.setXXX(null));
removeIf
removeIf is a default method in Collection.
Use removeIf for ArrayList O(n) instead of using Iterator.remove which is O(mn)
list.removeIf(s -> s.length() == 0);
long result= list.stream().collect(Collectors.counting());
Collectors.joining joins the stream elements for a given delimiter, prefix and suffix.
String result= list.stream().collect(Collectors.joining(",","(",")"));
int result = list.stream().collect(Collectors.summingInt(i->i));
Map<String,String> map = streak.collect(Collectors.toMap(k->k, v->v+v));
stream.findFirst().ifPresent(System.out::println);
streams cannot be reused. The stream is closed after you call any terminal operation.
Word Count:
groupBy aggregate
https://www.javacodegeeks.com/2015/03/jdk-8-streams-and-grouping.html
http://www.nurkiewicz.com/2014/07/grouping-sampling-and-batching-custom.html
Map collect = wordsList.stream().collect(groupingBy(Function.identity(), counting()));
Map map = "abcabc".chars().mapToObj(c -> (char) c) .collect(Collectors.groupingBy(c -> c, Collectors.counting()));
Map countMap = Files.lines(file).flatMap(line -> SPLITTER.splitToList(line).stream())
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
Method and Constructor References
XClass::aMethod, XClass::new
list.sort(String::compareToIgnoreCase);
stream.forEach(System.out::println)
Troubleshooting
When compiler complains: incompatible types: cannot infer type-variable(s),try to declare an explicit type to provide enough type information to compiler:
Map<K1, V1> to Map<K2, V2>
new HashMap<String, ValueClass>().entrySet().stream().collect(Collectors.toMap((final Entry<String, ValueClass> e) -> LocalDate.parse(e.getKey()), e -> e.getValue()));
Java 8 Time API
LocalDate/LocalTime/LocalDateTime - no time zone, good for store birthday
ZonedDateTime
date1.until(date2, ChronoUnit.DAYS),
date1.plusDays(1)
DateTimeFormatter - thread safe
-- Prefer it than SimpleDateFormat
LocalDate.parse("2016-10-06")
LocalDateTime.parse("2016-10-06", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Convert Date to ZonedDateTime
ZonedDateTime.ofInstant(date.toInstant(), ZoneOffset.UTC)
Month Enum
LongAdder vs AtomicLong
Related
Java Tips, Tricks and Traps
Using Optional
- as return value, field (Optional
Optional.ofNullable/orElse(T value)/orElseThrow
ifPresent(Consumer consumer)/orElseThrow(XException::new)
Map + ConcurrentHashMap
ConcurrentHashMap<String, Integer> wordMap = new ConcurrentHashMap<String, Integer>(16, 0.9f, 1);
compute, computeIfAbsent, computeIfPresent
- the current (existing or computed) value associated with the specified key, or null if the computed value is nulltargets.computeIfAbsent(ticket[0], k -> new PriorityQueue()).add(ticket[1]);
counters.computeIfAbsent(name, k -> new AtomicInteger()).incrementAndGet();
map.computeIfAbsent("key", k -> new LongAdder()).increment();
Instead of:
if (!map.containsKey(sum)) {
map.put(sum, i);
}
map.getOrDefault(key, defaultValue)
wordMap.merge(word, occurrence, (key, value) -> wordMap.getOrDefault(key, 0) + value);
wordMap.reduceValues(1,(count1,count2) -> count1+count2);
concurrentHashMap.search(threshold, (k, v) -> v > 1000 ? k : null);
Lambda
iterable.forEach(x -> x.setXXX(null));
removeIf
removeIf is a default method in Collection.
Use removeIf for ArrayList O(n) instead of using Iterator.remove which is O(mn)
list.removeIf(s -> s.length() == 0);
list.replaceAll(s -> s.toUpperCase());
list.sort((x, y) -> x.length() – y.length());
Arrays.sort(intervals, (a, b) -> Integer.compare(a.start,b.start));
Arrays.sort(intervals, (a, b) -> a.start - b.start);
Arrays.sort(intervals, (a, b) -> Integer.compare(a.start,b.start));
Arrays.sort(intervals, (a, b) -> a.start - b.start);
logger.finest(() -> complexMsg());
lineCount = Files.lines(path).count();
Collectors
toImmutable
toImmutable
.collect(collectingAndThen(toList(),Collections::unmodifiableList))
List to map:
list.stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getName())); - keyMapper, valueMapper
Convert to a different map - TreeMap
.collect(Collectors.toMap(keyMapper, valueMapper,(k,v) ->{ throw new RuntimeException(String.format("Duplicate key %s", k));}, TreeMap::new)); - mergeMapper, mapSupplier
stream().collect(Collectors.groupingBy(xxx));
list.stream().collect(Collectors.toMap(x -> x.getId(), x -> x.getName())); - keyMapper, valueMapper
Convert to a different map - TreeMap
.collect(Collectors.toMap(keyMapper, valueMapper,(k,v) ->{ throw new RuntimeException(String.format("Duplicate key %s", k));}, TreeMap::new)); - mergeMapper, mapSupplier
stream().collect(Collectors.groupingBy(xxx));
mapStream.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
long result= list.stream().collect(Collectors.counting());
Collectors.joining joins the stream elements for a given delimiter, prefix and suffix.
String result= list.stream().collect(Collectors.joining(",","(",")"));
int result = list.stream().collect(Collectors.summingInt(i->i));
Map<String,String> map = streak.collect(Collectors.toMap(k->k, v->v+v));
stream.findFirst().ifPresent(System.out::println);
streams cannot be reused. The stream is closed after you call any terminal operation.
Word Count:
groupBy aggregate
https://www.javacodegeeks.com/2015/03/jdk-8-streams-and-grouping.html
http://www.nurkiewicz.com/2014/07/grouping-sampling-and-batching-custom.html
Map
Map
Map
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
Method and Constructor References
XClass::aMethod, XClass::new
list.sort(String::compareToIgnoreCase);
stream.forEach(System.out::println)
Stream
List to map:
list.stream().collect( Collectors.toMap(Perseon::getId, Perseon::getAge));
toString
flatMap
Combination of map and flatten. The parameter mapper function returns a list of stream, flatMap flatten them into a Stream of single value.
slices.stream().map(slice -> slice.getReplicas()).flatMap(replicas -> replicas.stream())
.map(replica -> replica.getCoreUrl()).collect(Collectors.toList())
ArrayList.toString()
List to map:
list.stream().collect( Collectors.toMap(Perseon::getId, Perseon::getAge));
toString
flatMap
Combination of map and flatten. The parameter mapper function returns a list of stream, flatMap flatten them into a Stream of single value.
slices.stream().map(slice -> slice.getReplicas()).flatMap(replicas -> replicas.stream())
.map(replica -> replica.getCoreUrl()).collect(Collectors.toList())
ArrayList.toString()
ArrayList class extends AbstractList class, which extends AbstractCollection class which contains a toString() method
String.join(", ", list);
Troubleshooting
When compiler complains: incompatible types: cannot infer type-variable(s),try to declare an explicit type to provide enough type information to compiler:
Map<K1, V1> to Map<K2, V2>
new HashMap<String, ValueClass>().entrySet().stream().collect(Collectors.toMap((final Entry<String, ValueClass> e) -> LocalDate.parse(e.getKey()), e -> e.getValue()));
Java 8 Time API
LocalDate/LocalTime/LocalDateTime - no time zone, good for store birthday
ZonedDateTime
date1.until(date2, ChronoUnit.DAYS),
date1.plusDays(1)
DateTimeFormatter - thread safe
-- Prefer it than SimpleDateFormat
LocalDate.parse("2016-10-06")
LocalDateTime.parse("2016-10-06", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Convert Date to ZonedDateTime
ZonedDateTime.ofInstant(date.toInstant(), ZoneOffset.UTC)
Month Enum
LongAdder vs AtomicLong
Related
Java Tips, Tricks and Traps