说明:这是2007年复习SCJP期间的学习笔记(JavaSE 5.0),有部分遗失。现在整理一下发到Blog上,一方面做个备份,另一方面分享出来,希望对需要的人有用。
------------------------
第七部分 范型和集合
1、hashCode(): 返回一个表示该对象的散列代码的int值。
toString(): 为使人们读懂类对象的意义,需要重写toString()。
equals(): 如果不重写equals(),就不能把该对象用作散列表中的键。重写equals()使类对象能够被视为相同的,指定通过那些属性判断对象完全相等。永远不会有完全相等的对象。
2、重写equals()方法:
public boolean equals(Object o){ //重写equals方法
//确保测试类型是正确。
if((o instanceof Test)&&(((Test)o).getValue()==this.value))
{ retrun true; }
else { return false; }
}
3、重写hashCode()方法:
Object类中的默认散列码方法总是为每个对象产生一个唯一号。
hashCode()实现应采用相同的实例变量。
搜索对象与集合中的对象必须具有完全相同的散列码值,并且equals()方法也返回true。
4、瞬态变量容易与equals和散列码设计混淆,如果必须把变量标识为瞬态的,请不要用它确定对象的散列码或相等性,不过这并不违法(编译不会失败)。
5、java.util.Collection接口:包含多种集合常用的方法声明,List/Queue/Set扩展自它。没有一个Map有关类扩展自它。
6、java.util.Collections类:处理集合的静态实用方法。同java.util.Arrays都继承于Object类。
7、集合的4种基本形式:
List事物列表、Set唯一事物、Map唯一ID的事物、Queue按顺序排序。
8、一个类可以是未分类、未排序的,但不可能是分类但未排序的,因为分类是排序的一种特殊类型。
分类顺序和通过插入、访问或索引的排序是不同的。
9、HashSet----未排序,未分类。
LinkedHashSet----排序,未分类。
TreeSet----两种分类集合之一(另一个是TreeMap),保证元素按照元素的自然顺序进行升序排序。它还可以通过使用Comparable或Comparator为集合提供自己的规则,说明自然顺序应该是什么样的。
Map----把唯一键映射为具体值,键和值二者都是对象。只需向集合要求一些值或一些键。同Set一样,Map依赖于equals()方法来确定两个键是相同的还是不同的。
HashMap----提供一种未分类、未排序的Map,需要Map而不关心其顺序。允许一个null键和多个null值。
Hashtable----是HashMap的同步版本,不允许任何内容为null。
LinkedHashMap----保护插入顺序。
TreeMap----是个分类Map,按照元素自然顺序分类。允许定义自己的排序规则,以指定元素排序时它们相互之间应该如何比较。
PriorityOueue----基本队列也可以用LinkedList进行处理。按照自然顺序或根据Comparator进行排序的。
10、排序集合和数组:
ArrayList<String> stuff=new ArrayList<String>;
Collections.sort(stuff);
11、Comparable接口:由Collections.sort()和Arrays.sort()方法用来分别排序对象的列表和数组。
要实现Comparable一个类必须实现compareTo()。
int x = thisObject.compareTo(anotherObject);
compareTo()的返回值: 负数 ---- thisObject < anotherObject
0 ---- thisObject = anotherObject
正数 ---- thisObject > anotherObject
当重写equals()时,必须接受一个Object类型参数。当重写compareTo()时,应该接受正在排序的类型的参数。
12、Comparator:创建一个类负责排序,不用修改要排序的类。
Collections.sort(list,comparator);
排序数组或集合,内部元素也都必须是相互可比较的。
13、搜索数组或集合:
使用binarySearch()方法执行搜索,返回被搜索元素的索引。
若集合中不含该元素,返回该元素的插入位置。
被搜索的集合或数组必须先经过排序。若未经过排序,搜索的结果将是不可预测的。
没有以自然顺序进行排序,必须以自然顺序进行搜索。
以Comparator排序,必须以Comparator搜索。
14、返回 > 则交换位置。
返回 < 位置不变。
15、Arrays和Lists转换:
Lists和Sets类有toArray()方法,并且Arrays类有一个asList()的方法。
使用asList()方法时,数组和列表就连接在一起。更新其中之一时,其他的自动更新,即修改array元素影响list元素,修改list元素影响array。
16、对分类的集合进行排序,则插入元素必须是可相互比较的(同类的,一般不同类型不可相互比较),否则抛出异常。
17、使用Maps的类时,作为键的元素必须重写hashCode()和equals()。
枚举类已经重写了hashCode()和equals()。
公式创建的散列码越唯一,检索的速度就越快。
18、PriorityQueue类:
offer()方法:像队列中添加元素。
poll()方法:返回最高优先级的项,并删除之。
peek()方法:返回最高优先级的项,不删除。
19、声明一个具有<Object>的类型参数的List生成的集合的工作方式几乎与Java5原非泛型集合相同。
20、可以混用正确的泛型代码和较老的非泛型代码,但编译器会产生警告。
21、使用遗留集合时,注意解箱问题。非泛型集合get()方法始终返回一个类型为java.lang.Object的引用:
List test=new ArrayList();
int x=(Integer)test.get(0); //必须强制转换。
22、保持引用类型和它引用的对象的泛型类型相同。
23、使用泛型:List<Animal> animals=new ArrayList<Animal>();
animals.add(new Cat()); //可以插入泛型类的子类型,但实际上这是遗留代码。
animals.add(new Dog());
24、使用通配符<?>:
List<? extends Animal>:允许使用Animal或扩展自Animal的任何类型,但将设置为只读的(不能再往里添加任何对象)。
声明一个方法来接受实现了Serializable接口类型的东西,仍要使用extends:
Void foo(List<? extends Serializable> list){ }
List<? super A>:可以接受super右边的类型或任何它的超类型。可以添加右边或其超类的对象于其中。
25、public void foo(List<?> list) //任何类型都可以匹配,但不能插入任何类型。
{}
public void foo(List<Object> list) //只能接受List<Object>类型。
{}
List<? extends Object>和List<?>绝对等同。
26、通配符只能针对引用声明使用(参数、变量、返回类型等)。
27、泛型声明:<E>是传递进来的类型占位符。可以在类定义中使用一种形式的通配符来为可用作类型参数的类型指定范围。
28、泛型方法:我们可以在没有特定类型的情况下声明方法,然后基于传递给方法的类型获得类型信息。
public <T> void makeArrayList(T t){ //泛型方法在方法返回类型前声明泛型。
List<T> list=new ArrayList<T>();
list.add(t);
}
然后,通过Dog实例使用makeArrayList()方法:
Test t=new Test();
t.makeArrayList(new Dog());
界限也可以放在声明类型上:
public <T extends Number> void makeArrayList(T t) { }
29、类名称、类参数占位符、变量标识符之间没有命名冲突。
30、通配符<?>不能用于泛型类和方法声明,只能用于参数、变量、返回类型。
31、Map<E1,E2>代表两个参数泛型,<>可以嵌套。
32、Collection.reverse(); 反转序列。
Comparator c = Collection.reverseOrder(); 以相反方式排序的Comparator。
33、通过参数隐藏变量可导致泛型集合改变为非泛型。
34、LinkedList.add() à 添加到末尾。
LinkedList.remove() à 从开始删除。
35、未重写hashCode()将按照原始方式散列,且equals()方法失效。
重写hashCode()后若键值相同时,相同的键将不被加入。
36、若搜索后元素不存在,则返回插入位置,实际插入表示为:-(插入点)-1。
第一个元素插入点表示:-1。
第二个元素插入点表示:-2。
……
37、数组或集合类的搜索前必先排序。