几个小地方
1.重载最好是有层次的继承关系,否则不要写的太“相似”,尽量少用重载,多重写,但是要考虑复用性
public class Card { public static String classify(Set<?> set) { return "set"; } public static String classify(List<?> list) { return "list"; } public static String classify(Collection<?> collection) { return "unknown"; } public static void main(String[] args) { Collection<?>[] collections = { new HashSet<String>(), new ArrayList<String>() }; for (Collection<?> c : collections) { System.out.println(classify(c)); } } }
这里会编译通过,但是都是unknown,因为程序不知道哪个合适,只能找一个一定合适的,因为都是Collection的子类。
这里我们可以变体一下就ok了
public static String classify(Collection<?> collection) { // return "unknown"; return collection instanceof Set ? "set" : collection instanceof List ? "list" : "unknown"; }
2.永远不要返回NULL,要返回空的集合或者数组,这点真是很常见的错误习惯
- 一是增加了未处理null的风险
- 二是让处理的逻辑看起来很奇怪,为什么null,null了为什么还要进来处理
对于集合我们可以为了性能,返回一个不可变的集合。下面的代码就是这样做的,使用了 Collections.emptyList 方法。如果你要返回一个 Set,可以使用 Collections.emptySet ;如果要返回 Map,则使用 Collections.emptyMap 。但是请记住,这 是一个优化,很少需要它。如果你认为你需要它,测量一下前后的性能表现,确保它确实有帮助
public List<Card> getCards() { return nums == 0 ? Collections.emptyList() : new ArrayList<>(nums); }
数组的情况与集合的情况相同。 永远不要返回 null,而是返回长度为零的数组。 通常,应该只返回一个正确长 度的数组,这个长度可能为零。 如果你认为分配零长度数组会损害性能,则可以重复返回相同的零长度数组,因为所有零长度数组都是不可变的:
private static final Card[] EMPTY_CARD_ARRAY = new Card[0]; public Card[] getCards() { return Card.EMPTY_CARD_ARRAY; }
3.Optional的一点用法
public static <E extends Comparable<E>> Optional<E> max(Collection<E> c) { if (c.isEmpty()) { return Optional.empty(); } E result = null; for (E e : c) { if (result == null || e.compareTo(result) > 0) { result = Objects.requireNonNull(e); } } return Optional.of(result); }
public static void main(String[] args) { List<String> words = new ArrayList<>(); words.add("a"); words.add("b"); words.add("c"); String maxWord = max1(words).orElse("no word"); System.out.println(maxWord); }
Optional在编译时给null是会编译失败的,并且上面的可以用下面一个替代。
public static <E extends Comparable<E>> Optional<E> max1(Collection<E> c) { return c.stream().max(Comparator.naturalOrder()); }
4.可以实现Iterable接口,这样所有类都能迭代操作
5.对于任何需要精确答案的计算,不要使用 float 或 double 类型。如果希望系统来处理十进制小数点,并且 不介意不使用基本类型带来的不便和成本,请使用 BigDecimal。使用 BigDecimal 的另一个好处是,它可以完全控制 舍入,当执行需要舍入的操作时,可以从八种舍入模式中进行选择。如果你使用合法的舍入行为执行业务计算,这将 非常方便。如果性能是重要的,那么你不介意自己处理十进制小数点,而且数值不是太大,可以使用 int 或 long。 如果数值不超过 9 位小数,可以使用 int;如果不超过 18 位,可以使用 long。如果数量可能超过 18 位,则使用 BigDecimal。
今天加入了K神的微信群,太有趣了,哈哈哈,好久没这么开心了。