构建JavaAPI的艺术:Do's and Don'ts 英文

微风

2019/03/24 发布于 技术 分类

文字内容
1. jonathan.giles@microsoft.com
14. Return Type Non-null Return Value String “” (empty string) List / Set / Map / Iterator Use Collections class, e.g. Collections.emptyList() / Collections.emptySet() / etc Stream Stream.empty() Array Return an empty, zero-length array All other types Consider using Optional
16. // getFastest returns Optional, but if the cars list is empty, it // returns Optional.empty(). In this case, we can choose to map this to an // invalid value. Car fastestCar = getFastest(cars).orElse(Car.INVALID); // If the orElse case is expensive to calculate, we can also use a Supplier // to only generate the alternate value if the Optional is empty Car fastestCar = getFastest(cars).orElseGet(() -> searchTheWeb()); // We could alternatively throw an exception Car fastestCar = getFastest(cars).orElseThrow(MissingCarsException::new); // We can also provide a lambda expression to operate on the value, if it // is not empty getFastest(cars).ifPresent(this::raceCar)
17. // Whilst it is ok to call get() directly on an Optional, you risk a // NoSuchElementException if it is empty. You can wrap it with an // isPresent() call as shown below, but if your API is commonly used like // this, it suggests that Optional might not be the right return type Optional result = getFastest(cars); if (result.isPresent()) { result.get().startCarRace(); }
18. // Some people just want to see the world burn public Optional getFastest(List cars) { if (cars == null cars.isEmpty()) { return null; } ... }
45. We’ve been using them all along in the JDK: public static Boolean valueOf(boolean b) { return b ? Boolean.TRUE : Boolean.FALSE; } and there are always new static factories being added, e.g.: static static static // ....and List of(); List of(E e1); List of(E e1, E e2); so on (there are 12 overloaded versions of this method!) static List of(E... elems);
46. public class RandomIntGenerator { private final int min; private final int max; public int next() { … } public RandomIntGenerator(int min, int max) { this.min = min; this.max = max; } public RandomIntGenerator(int min) { this(min, Integer.MAX_VALUE); } public RandomIntGenerator(int max) { this(Integer.MIN_VALUE, max); } Duplicate method } https://jlordiales.me/2012/12/26/static-factory-methods-vs-traditional-constructors/
47. public class RandomIntGenerator { private final int min; private final int max; private RandomIntGenerator(int min, int max) { this.min = min; this.max = max; } public static RandomIntGenerator between(int min, int max) { return new RandomIntGenerator(min, max); } public static RandomIntGenerator biggerThan(int min) { return new RandomIntGenerator(min, Integer.MAX_VALUE); } public static RandomIntGenerator smallerThan(int max) { return new RandomIntGenerator(Integer.MIN_VALUE, max); } public int next() {...} } https://jlordiales.me/2012/12/26/static-factory-methods-vs-traditional-constructors/
50. Interface Signature Summary UnaryOperator T apply(T t) UnaryOperator extends Function BinaryOperator T apply(T t1, T t2) BinaryOperator extends BiFunction Predicate boolean test(T t) Takes a T, returns a primitive boolean value Function R apply(T t) Takes a T, returns an object of type R Supplier T get() Takes no argument, returns an object of type T Consumer void accept(T t) Takes a T, returns nothing
51. Interface Signature Example UnaryOperator T apply(T t) List names = Arrays.asList("bob", "josh", "megan"); names.replaceAll(String::toUpperCase); BinaryOperator T apply(T t1, T t2) Map salaries = new HashMap<>(); salaries.put("John", 40000); salaries.replaceAll((name, oldValue) -> name.equals("Freddy") ? oldValue : oldValue + 10000); Predicate boolean test(T t) List namesWithA = names.stream() .filter(name -> name.startsWith("A")) .collect(Collectors.toList()); Function R apply(T t) Map nameMap = new HashMap<>(); Integer value = nameMap.computeIfAbsent("Giles", String::length); Supplier T get() int[] fibs = {0, 1}; Stream fibonacci = Stream.generate(() -> { int result = fibs[1]; int fib3 = fibs[0] + fibs[1]; fibs[0] = fibs[1]; fibs[1] = fib3; return result; }); Consumer void accept(T t) List names = Arrays.asList("John", "Freddy", "Samuel"); names.forEach(name -> System.out.println("Hello, " + name)); http://www.baeldung.com/java-8-functional-interfaces
54. JButton btn = new JButton(“Click Me”); btn.addMouseListener(new MouseListener() { @Override public void mouseReleased(MouseEvent e) { .. } @Override public void mousePressed(MouseEvent e) { .. } @Override public void mouseExited(MouseEvent e) { .. } @Override public void mouseEntered(MouseEvent e) { .. } @Override public void mouseClicked(MouseEvent e) { .. } });
55. JButton btn = new JButton(“Click Me”); btn.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { .. } });
56. Rectangle rect = new Rectangle(); rect.setOnMouseClicked(new EventHandler() { @Override public void handle(MouseEvent e) { print(e); } }); Rectangle rect = new Rectangle(); rect.setOnMouseClicked(e -> print(e));
69. jonathan.giles@microsoft.com