Using Java 8


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);

compute, computeIfAbsent, computeIfPresent
the current (existing or computed) value associated with the specified key, or null if the computed value is null
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);


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);
logger.finest(() -> complexMsg());
lineCount = Files.lines(path).count();


Collectors
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));
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 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)

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() 
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

Labels

adsense (5) Algorithm (69) Algorithm Series (35) Android (7) ANT (6) bat (8) Big Data (7) Blogger (14) Bugs (6) Cache (5) Chrome (19) Code Example (29) Code Quality (7) Coding Skills (5) Database (7) Debug (16) Design (5) Dev Tips (63) Eclipse (32) Git (5) Google (33) Guava (7) How to (9) Http Client (8) IDE (7) Interview (88) J2EE (13) J2SE (49) Java (186) JavaScript (27) JSON (7) Learning code (9) Lesson Learned (6) Linux (26) Lucene-Solr (112) Mac (10) Maven (8) Network (9) Nutch2 (18) Performance (9) PowerShell (11) Problem Solving (11) Programmer Skills (6) regex (5) Scala (6) Security (9) Soft Skills (38) Spring (22) System Design (11) Testing (7) Text Mining (14) Tips (17) Tools (24) Troubleshooting (29) UIMA (9) Web Development (19) Windows (21) xml (5)