[Effective Java 3rd Edition](https://www.amazon.co.jp/Effective-Java-%E7%AC%AC3%E7%89%88-%E3%], which is a must-have book for intermediate Java users and above. 82% B8% E3% 83% A7% E3% 82% B7% E3% 83% A5% E3% 82% A2% E3% 83% BB% E3% 83% 96% E3% 83% AD% E3% 83% 83% E3% 82% AF-ebook / dp / B07RHX1K53) has a Kindle version, so I will summarize it.
Previous: Effective Java 3rd Edition Chapter 6 enums and annotations Next: Effective Java 3rd Edition Chapter 8 Methods
//Anonymous class
Collections.sort(words, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return Integer.compare(o1.length(), o2.length());
}
});
//Use lambda
Collections.sort(words, (o1, o2) -> Integer.compare(o1.length(), o2.length()));
//Comparator construction method
Collections.sort(words, comparingInt(String::length));
//Even shorter in Java 8
words.sort(comparingInt(String::length));
--Example of enum with function object fields and constant-specific behavior.
public enum Operation {
PLUS("+", (x, y) -> x + y),
MINUS("-", (x, y) -> x + y),
TIMES("*", (x, y) -> x + y),
DIVIDE("/", (x, y) -> x + y);
private final String symbol;
private final DoubleBinaryOperator op;
Operation(String symbol, DoubleBinaryOperator op) {
this.symbol = symbol;
this.op = op;
}
@Override public String toString() {
return symbol;
}
public double apply(double x, double y) {
return op.applyAsDouble(x, y)
}
}
--Type of method reference
--static ・ ・ ・ ʻInteger :: parseInt --Bound ・ ・ ・ ʻInstant.now () :: isAfter
--Unbound ・ ・ ・ String :: toLowerCase
--Class constructor ・ ・ ・ TreeMap <K, V> :: new
--Array constructor ・ ・ ・ ʻint [] :: new`
--If the method reference is shorter and clearer, use the method reference, otherwise use the lambda.
--java.util.Function
has 43 interfaces, all of which cannot be remembered, but as long as you remember the 6 basic interfaces, the rest of the interfaces can be derived when needed.
--ʻOperatorinterface represents a function whose resulting type is the same as the argument. --The
Predicateinterface takes an argument and returns a boolean. --The
Functioninterface returns a type different from the argument. --The
Supplierinterface takes no arguments and returns a value. (Provide results) --The
Consumer` interface takes arguments and returns nothing. (Consume arguments)
interface | Function signature | Example |
---|---|---|
UnaryOperator |
T apply(T t) | String::toLowerCase |
BinaryOperator |
T apply(T t1, T t2) | BigInteger::add |
Predicate |
boolean test(T t) | Collection::isEmpty |
Function<T,R> | R apply(T t) | Arrays::asList |
Supplier |
T get() | Instant::now |
Consumer |
void accept(T t) | System.out::println |
--Depending on the process, there are cases where it is best to do it in a stream and cases where it is best to do it in a loop. In many cases, it is best to combine the two methods. --If you're not sure if it's better to do it in a stream or a loop, try both.
--The essence of stream pipeline programming is a function object with no side effects.
--The termination operation forEach
should be used only to display the result, not to perform the calculation.
--Important collector factories are toSet
, toMap
, groupingBy
, joining
.
--When writing a method that returns a sequence of elements, some users may want to treat it as a stream, others may want to loop. Try to adapt to both users. --If you already have elements in the collection, or if the number of elements in the sequence is small enough to justify the creation of a new collection, return a standard collection such as ArrayList. If not, consider implementing a special collection. --If you can't return a collection, return Stream or Iterable, whichever seems more natural.
--At the time of Java release, it had synchronization and wait / notify
, and built in thread support.
--Java5 introduced the java.util.concurrent
library, which has a concurrent collection and executor framework.
--Java7 introduced a high-performance fork-join
framework for splitting in parallel.
--In Java8, streams are introduced and can be parallelized with a single call to the parallel
method.
--Pipeline parallelization of streams should not be done unless there is good reason to believe that it will maintain correctness and improve performance.
--Ensure that your code remains correct when running in parallel, and carefully measure performance under real-world conditions.
--The default number of threads for .parallel ()
is number of machine cores-1
.
Stream pipeline parallelization to count prime numbers
static long pi(long n) {
return LongStream.rangeClosed(2, n)
.parallel()
.mapToObj(BigInteger::valueOf)
.filter(i -> i.isProbablePrime(50))
.count();
}
Recommended Posts