容器
填充容器
- 和数组一样,容器也有相应的Collections类来扩充容器的使用功能,使用fill()和nCopies()可以填充容器。问题:填充的对象单一。
- 使用构造器。问题:无法自动填充
如何更好的解决填充问题?
- 使用生成器Generator
填充一个Collection1
2
3
4
5
6
7public class Generators {
public static <T> Collection<T> fill(Collection<T> coll, Generator<T> gen, int n) {
for(int i = 0; i < n; i++)
coll.add(gen.next());
return coll;
}
}
也可以使用适配模式,定义适配Gneerator接口的Collection。
- 使用自定义的只读Collection
如何自定义?
容器中有很多Abstract类,这些类已经实现了大部分Collection(Map)的功能,我们需要实现的已经很少了,如果只是需要定制一个只读的Collection(Map),需要做的事情就更少。
- 创建一个MyMap,我们需要继承AbstractMap,实现里面的抽象方法,Set
entrySet(); - 从这个方法我们可以看出,还需要定义实现了Entry接口的对象和容纳这个对象的Set;
- 自定义MySet,需要继承AbstractSet,实现里面的抽象方法:int size()和Interator interator();
- 同时,这也说明需要定义一个实现了Iterator接口的对象,作为返回。
那些只读的数据可以提前封装到Entry类中,但是这样会有一个问题:我每次创建一个Map,都需要把这些Entry类给生成一次,这样就造成了大量对象的创建,给内存空间和GC带来了很大的压力,有什么比较好的解决方案么?
使用享元模式。
什么是享元模式?
大致的意思是将一个完整的对象和这个对象的一个外部(表面)对象表示关联起来,这样通过这个外部对象可以取得完整的对象,通常是使用map来做一个绑定。优势:
- 不需要再创建大量的相同对象
- 创建的时间也减少
享元模式我感觉就像是缓存。
Collection的功能方法
LIst有get(index)的方法,Set没有,因为Set的元素顺序是自己维护的。
Collection中方法可选表示什么意思?
表示实现了Collection(实际上是继承AbstractCollection)的类按需求可以选择的去实现这些方法,因此AbstractCollection会给默认的实现,尽管这些实现基本上是返回一个UnsupportedOperationException异常。
这样处理的好处是什么?
尽量使用一个接口满足绝大部分人的需求:比如两个不同需求的LIst:固定尺寸的List,不可修改的List,接口上前者比后者会多一个set()方法,因此需要两个不同的接口。但是对于容器而言,不同的需求是无穷无尽的,因此为了防止接口爆炸,兼容绝大多数的需求,实现易学易用,JAVA选择了牺牲一下接口应该具有的安全性。
上面提到的尺寸固定的List就是Arrays中的内部类,Arrays.asList()返回的List,它没有做add()方法的定义。而不可修改的List是指Collections.unmodifiableList()返回的List.
优先队列
[优先队列]https://www.cnblogs.com/CarpenterLee/p/5488070.html
LIst
最简单的List需要继承AbstractList并且需要实现get(index)和size()方法。
Set
如果加入的元素没有实现所要求的方法,在使用的时候或者去重无效,或者抛出异常。
Map
equal()和hashCode()分别扮演了怎樣的角色?
hashCode()计算所在的散列值,但是两个对象也会出现散列值相同的情况,这时候再通过equal()去判断是否相等。
HashMap的性能因子
容量:表的槽位
初始容量:初始表的槽位
尺寸:当前已使用的槽位
负载因子:尺寸/容量,当实际比例达到负载因子,会自动扩充容量(再散列)。