集合与泛型
-
ArrayList不是唯一的集合
-
TreeSet 以有序状态保持并可防止重复 HashMap 可用成对的name/value来保存与取出 LinkedList 针对经常插入或删除中间元素所设计的高效率集合 HashSet 防止重复的集合,可快速查找相符的元素 LinkedHashMap 类似HashMap,但可记住元素插入的顺序,也可以设定成依照元素上次存取的先后来排序 -
泛型意味着更好的类型安全性
-
泛型:
- 创建被泛型化的实例
- 声明与指定泛型类型的变量
- 声明(与调用)取用泛型类型的方法
-
使用泛型的类
-
ArrayList<String> thisList =new ArrayList<String>; //会被编译器看成 public class ArrayList<String> extends AbstractList<String>...{ public boolean add(String o) //更多代码 }
-
运用泛型的方法
-
使用定义在类声明的类型参数
-
public class ArrayList<E> extends AbstractList<E>...{ public boolean add(E o) }
-
使用未定义的在类声明的类型参数
-
public <T extends Animal>void takeThing(ArrayList<T> list)
-
-
对于泛型来说,extends这个关键词代表“是一个… …”,且适用于类和接口
-
调用单一参数的sort(List o)方法代表由list元素上的comparentTo()方法来决定顺序,因此元素必须要实现Comparable这个接口
-
调用sort(List o,Comparator c)方法代表不会调用list元素的compare()方法,而会使用Comparator的compare()方法。这意味着list元素不需要实现Comparable
-
Collection的3个主要接口
-
List:对付顺序的好帮手
是一种知道索引位置的集合,可以有多个元素引用相同的对象
-
Set:注重独一无二的性质
不允许重复的集合,不会有多个元素引用相同的变量
-
Map:用key来搜索的专家
使用成对的键值和数据值,两个key可以引用相同的对象,但key不能重复,典型的key会是String,但也可以是任何对象
-
-
引用相等性:堆上同一对象的两个引用
引用到堆上同一个对象的两个引用是相等的
-
对象相等性:堆上的两个不同对象在意义上是相同的
如果你想要吧两个不同的Song对象视为相等的,就必须覆盖过从Object继承下来的hashCode()方法与equals()方法
-
如果foo与bar两对象相等,则foo.equals(bar)会返回true,且两者的hashCode()也会返回相同的值
-
HashSet检查重复:
当把对象加入HashSet时,它会使用对象的hashcode值来判断对象加入的位置。但同时也会与其他已经加入的对象的hashcode作对比,如果没有相符的hashcode,HashSet就会假设新对象没有重复出现
-
但有相同hashCode()的对象也不一定相等
-
若equals()被覆盖过,则hashCode()也必须被覆盖
-
hashCode()的默认行为时对在heap上的对象产生独特的值。如果你没有override过hashCode(),则该class的两个对象怎样都不会认为是相同的
-
equals()的默认行为是执行==的比较。也就是说会去测试两个引用是否对上heap上同一个对象。如果equals()没有被覆盖过,两个对象永远都不会视为相同的,因为不同的对象有不同的字节组合
-
a.equals(b)必须与a.hashCode()==b.hashCode()等值
但a.hashCode()==b.hashCode()不一定要与a.equals(b)等值
-
Map中的元素实际上是两个对象:关键字和值。值可以重复,但是key不行
-
import java.util.HashMap; public class TestMap { public static void main(String[] args) { HashMap<String,Integer> scores =new HashMap<String,Integer>(); scores.put("Kathy",42); scores.put("Bert",343); scores.put("Skyler",420); System.out.println(scores); System.out.println(scores.get("Bert")); } }
-
如果方法的参数是Animal的数组,它也能够取用Animal次类型的数组。也就是说,如果方法是这样声明的:void foo(Animal[] a){ } 若Dog有extend过Animal,你就可以用下列的两种方式调用: foo(anAnimalArray); foo(aDogArray);
-
如果把方法声明成取用ArrayList,它就只会取用ArrayList参数,ArrayList与ArrayList都不行
-
数组的类型是在运行期间检查的,但集合的类型检查只会发生在编译期间
-
在方法参数中使用万用字符<?>时,编译器会阻止任何可能破坏引用参数所指集合的行为,你能够调用list中任何元素的方法,但不能加入元素。也就是说,你可以操作集合元素,但不能新增集合元素