提示三十六
2022-07-25 本文已影响0人
飞絮搅青冥
提示三十六:使用 EnumSet 替代位属性。
EnumSet继承了AbstractSet并且实现了Cloneable,Serializable的接口,以前我都没有用过。它的性能与位域相当,所以遇到枚举集合时使用EnumSet性能会比较优秀。
public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
implements Cloneable, java.io.Serializable
书中有这样一段话“批量操作(如 removeAll 和 retainAll )是使用按位算术实现的,就像你手动操作位域一样“,我发现removeAll我还比较熟悉,但是retainAll之前也接触的比较少。于是我就随手写了一个test:
List<String> strings1 = Arrays.asList("hello", "world", "a");
List<String> strings2 = Arrays.asList("hello", "world", "two");
System.out.println(strings2.retainAll(strings1));
System.out.println(strings1);
System.out.println(strings2);
没想到居然报错了,java.lang.UnsupportedOperationException。发现是不能在循环中修改list,但是retainAll的源码分明是在循环中使用了Iterator去做的remove,而且retainAll这个方法既然能够被API提供出来,怎么连我这么简单的调用都会有问题。后面我试了一下,发现new一个ArrayList,然后用add一个个加元素进去就可以调用retainAll这个方法,原来问题出在了Arrays.asList
上。后来我仔细看了一下才发现虽然这里的asList看上去就是new了一个ArrayList,但是这个类是Arrays里面内部实现的一个ArrayList,而不是我们一般使用的java.util包里面的ArrayList类。看来以后遇到这种方法需要多加小心,不能想当然。
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
