1,集合
ArrayList不是唯一的集合
TreeSet 以有序状态保持,并可以防止重复
HashMap 可用成对的name/value来保存与取出
LinkList 针对经常插入或删除中间元素设计的高效率集合
HashSet 防止重复的集合,可以快速的寻找相符的元素
LinkedHashMap 类似HashMap,但是可以记住元素的顺序
可以使用TreeSet或则Collections.sort()方法 //public static void sort( List list)
ArrayList 有实现List这个接口所以可以将ArrayList传给sort //多态的威力
传入ArrayList<Song> 对象时编译无法运行
public class ArrayList<E> extends AbstractList<E> implements List<E> ...
public static <T extends Comparable<? super T> > void sort< List<T> list >
public <T extends Animal> void takething( ArrayList<T> list) 与 public void takething( ArrayList<Animal> list )不一样
<T extends Animail> 是方法声明的一部分,表示任何被申明为Animal或者Animal子型的ArrayList是合法的,但是第二种表示只有ArrayList<Animail>是合法的
回头看sort方法传入ArrayList<Song>时编译无法运行是应为Song没有extend(代表继承或实现)Comparable
public interface Comparable<T>{
int CompareTo( T o); //返回正值代表代表传入的小 负值代表传入的大 返回0代表相等
}
//调用sort< List<T> list>元素必须实现Comparable
class Song implements Comparable<Song>{
String title;
public int CompareTo( Song s){
return tittle.CompareTo( s.getTitle() );
}
public void getTitle(){
return tittle;
}
}
sort的另一种重载方法 它采用Comparator (自定义比较器)
interface Comparator<T>{
int compare( T o1, T o2);
}
如果传递给Comparator给sort()方法,则排序是由Comparator而不是元素的CompareTo()方法决定的
sort( List<T> list, Comparator<? super T> c ); //元素不需要实现Comparable 这个比较器可以用内部类实现
class ArtistCompare implements Comparator<Song>{
public int compare( Song o1, Song o2){
return o1.getArtist().CompareTo( o2.getArtist() );
}
}
Collection.sort( ArrayList<Song>, new ArtistCompare() );
2.处理重复数据的集合Set
Set集合用来处理重复元素,不会有多个元素引用相同的对象(addAll方法很好用 )
HashSet
如何判断对象是否相等
引用相等性 堆上同一个对象的两个引用,如果对两个引用调用hashCode(), 你会得到相同的结果。如果没有被覆盖的话hashCode()会返回每个对象特有的序列号
使用 == 来比较两个引用是否相等 如果引用到相同的对象字节组合也会一样
对象相等性 需要覆盖从Object类继承下来的hashCode() 和 equals() 方法, 你必须覆盖过hashCode()才能确定两个对象有相同的hashCode,也要确保以另一个对象做参数的equals()会返回true
if( foo.equals( bar) && foo.hashCode() == bar.hashCode() )
Set的工作方法:先找到hashCode相同的对象(缩小寻找成本), 然后调用equals()来检查对象是否真的相等 add方法会返回true or false
由Set的工作方法可以得出:
1.对象相等hashCode也相等
2.如果两个对象相等则 a.equals(b) 返回true
3.如果两个对象的hashCode相等则对象不一定相等,因此若equals被覆盖过则hashCode也必须要被覆盖
4. 若a.equals(b) 则a.hashCode() == b.hashCode(); 反之则不成立
TreeSet(保持元素有序)的对象必须是有实现Comparable 不然无法排序
或则使用重载,取用Comparator参数的构造函数
public class BookCompare implements Comparator<Book>{
public int compare( Book one, Book two ){
return (one.title.compareTo(two.title) );
}
}
BookCompare bCompare = new BookCompare();
TreeSet<Book> tree = new TreeSet<Book>( bCompare );
3,Map
Map:
HashMap
key value键值対 HashMap需要两个参数 关键字和值
泛型:
看下面的例子
public class TestGenericsl{
public static void main( String[] args ){
new TestGenericsl.go();
}
public void go(){
Animal[] animals = { new Dog(), new Cat(), new Dog() };
Dog[] dogs = { new Dog(),new Dog(),new Dog() };
takeAnimals( animails );
takeAnimals( dogs );
}
public void takeAnimals( Animal[] animals ){ //可以取用dogs参数 多态发挥作用 数组类型是在运行期间检查的
for( Animal a : animals ){
a.eat();
}
}
}
public class TestGenericsl{
public static void main( String[] args ){
new TestGenericsl.go();
new TestGenericsl.goDog(); //编译到这一步会报错,集合的类型检查只会发生在编译期间
}
public void go(){
ArrayList<Animal> animals = new ArrayList<Animail>();
animails.add( new Dog() );
animails.add( new Cat() );
animails.add( new Dog() );
}
public void goDog(){
ArrayList<Dog> dogs = new ArrayList<Dog>();
dogs.add( new Dog() );
dogs.add( new Dog() );
dogs.add( new Dog() );
}
public void takeAnimals( ArrayList<animals> animals ){ //如果把方法声明成ArrayList<animals> 它就会取用ArrayList<animals>参数 ArrayList<Dog>不行
for( Animal a : animals ){ //for循环可以操作集合和数组
a.eat();
}
}
}
public void takeAnimals( ArrayList<? extends Animal> animals ){ //extends代表继承和实现 <?>的声明编译器不会让你加入任何东西到集合中,但是可以调用list方法
for( Animal a : animals ){ //for循环可以操作集合和数组
a.eat();
}
}
public void takeAnimals( ArrayList<? extends Animal> animals ) 与
public <T extends Animal> void takeAnimals( ArrayList<T> animals) 一样
相当于声明参数问题 如果参数有多个声明就可以用ArrayList<T>替代