集合和集合框架
1、对象的可以通过数组和集合来存储,对象最常用的存储方式是集合。数组是固定长度的,集合的可变长度的。数组存放一种基本数据类型并且只能存一次,集合只适合于存储对象并且是不同的对象。容器的抽取形成集合框架体系。集合框架的最顶层是Collection。Collection下有List和Set,List,Set下也有很多常见的容器。出现这么多的容器的原因是每一个容器对数据的存储方式都有不同,这个存储方式成为数据结构。
2、java.util包中的Collection接口ArrayList类的使用 。
3、Collection集合基类有add,remove,contains,clear,iterator等方法,其子类List和Set继承此些方法。重点是Iterator迭代器和ListIterator列表迭代器(List集合特有的迭代器)。
Collection
|--List:元素是有序(元素存入和取出的顺序一致)的,元素可以重复,因为该集合体系有索引
|--ArrayList:底层数据结构是数组,查询速度快,线程不同步。
|--LinkedList:底层数据结构是链表,增删速度快,查询速度稍慢
|--Vector:底层是数组数据结构,和ArrayList功能一样,线程同步,一般不使用了。
|--Set:元素是无序的,元素不可以重复
|--HashSet:底层数据结构是哈希表,按哈希值的顺序存储,线程是非同步的。保证元素唯一性的是判断哈希值,如果相同还会判断equals方法是否为真。
|--TreeSet:可以对Set集合中的元素进行排序,可以默认按ACCII码表排序。底层数据结构是二叉树,保证元素唯一性的依据是compareTo方法返回0。TreeSet排 序的的第一种方式是使其具有比较性,需要实现Comparable接口,覆盖compareTo方法,是自然排序法。当元素自身不具有比较性时,让集合具有比较性,集合在初始化时就具备了比较方式,此时要定义比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。当两种比较方式都存在时,以比较器为主。
4、泛型:泛型是jdk1.5之后出现的新特性,为了解决安全问题。我们在定义数组的时候会定义不可更改的数据类型,而定义集合的时候就不会了,任何类型都可以存入集合,这就引发了安全问题。泛型就是解决这个安全问题。任何类型存入集合中都会在编译的时候通过,运行时输出结果后才提示异常。给集合加一个中括号,放入需要装入的数据类型,则可以在编译时就提示类型错误。泛型还避免了强制类型转换。
1 package test; 2 import java.util.*; 3 public class ListSet 4 { 5 public static void main(String[] args) 6 { 7 ArrayList<Integer> arr=new ArrayList<Integer>(); 8 arr.add(3); 9 arr.add(4); 10 Iterator<Integer> it=arr.iterator();//迭代器 11 while(it.hasNext()) 12 { 13 System.out.println(it.next()); 14 } 15 } 16 }
5、泛型格式:通过<>来定义要操作的引用数据类型;
写泛型的条件:出现<>,就需要定义泛型,<>就是用来接收类型的。
6、泛型类:早期在没有泛型的时候是利用Object基类来设置类似于泛型的机制,完成可扩展性特性。有了泛型后,用泛型类扩展程序功能。
1 package test; 2 public class ListSet 3 { 4 public static void main(String[] args) 5 { 6 //早期用Object完成扩展的做法 7 /* 8 Tool t=new Tool(); 9 t.setObject(new Worker()); 10 Worker worker=(Worker)t.getObject(); 11 */ 12 //现在的泛型类做法 13 Utility<Worker> w=new Utility<Worker>(); 14 w.setCla(new Worker()); 15 Worker worker=w.getCla(); 16 } 17 } 18 class Student 19 {} 20 class Worker 21 {} 22 class Tool 23 { 24 private Object obj; 25 public void setObject(Object obj) 26 { 27 this.obj=obj; 28 } 29 public Object getObject() 30 { 31 return obj; 32 } 33 } 34 //T为要传入泛型类的引用类型参数 35 class Utility<T> 36 { 37 private T t; 38 public void setCla(T t) 39 { 40 this.t=t; 41 } 42 public T getCla() 43 { 44 return t; 45 } 46 }
7、泛型方法和静态泛型方法
1 package test; 2 //泛型方法 3 public class FanXing 4 { 5 public static void main(String[] args) 6 { 7 S s=new S(); 8 s.show(4); 9 s.show(new Integer(2)); 10 s.show("sdfsdf"); 11 12 S1<TT> s1=new S1<TT>(); 13 s1.show(new TT()); 14 s1.print("dfsf"); 15 } 16 } 17 //泛型方法 18 class S 19 { 20 public <T> void show(T t) 21 { 22 System.out.println(t); 23 } 24 } 25 //泛型方法和泛型类 26 class S1<TT> 27 { 28 public void show(TT t) 29 { 30 System.out.println(t); 31 } 32 public <Q> void print(Q q) 33 { 34 System.out.println(q); 35 } 36 //静态泛型方法,不能调用类的泛型方法 37 public static <P> void show1(P p) 38 { 39 System.out.println(p); 40 } 41 } 42 class TT 43 {}
8、泛型接口极其应用
1 package test; 2 //泛型接口极其使用 3 public class FanXing 4 { 5 public static void main(String[] args) 6 { 7 InterImplement i=new InterImplement(); 8 i.function("sfdf"); 9 10 InterImp1<String> ii=new InterImp1<String>(); 11 ii.function("我是好人,不要杀我!"); 12 } 13 } 14 interface Inter<T> 15 { 16 void function(T t); 17 } 18 class InterImplement implements Inter<String> 19 { 20 public void function(String s) 21 { 22 System.out.println(s); 23 } 24 } 25 class InterImp1<T> implements Inter<T> 26 { 27 public void function(T t) 28 { 29 System.out.println(t); 30 } 31 }
9、泛型限定
1 package test; 2 import java.util.*; 3 //泛型限定 4 /* 5 * ?是通配符也是占位符; 6 * ? extends E:可以接收E类型或者E的子类型,是类型的上限 7 * ? super E:可以接收E类型或者E的父类型,是下限 8 */ 9 public class FXXD 10 { 11 public static void main(String[] args) 12 { 13 ArrayList<String> a=new ArrayList<String>(); 14 a.add("a"); 15 a.add("b"); 16 17 ArrayList<Integer> a1=new ArrayList<Integer>(); 18 a1.add(1); 19 a1.add(2); 20 21 printfx(a); 22 printfx(a1); 23 24 ArrayList<Person> p=new ArrayList<Person>(); 25 p.add(new Person("aaaa")); 26 p.add(new Person("bbbb")); 27 p.add(new Person("cccc")); 28 printt(p); 29 30 ArrayList<Student> s=new ArrayList<Student>(); 31 s.add(new Student("aaaa")); 32 s.add(new Student("bbbb")); 33 s.add(new Student("cccc")); 34 //printt(s); //error,因为ArrayList<Person> s=new ArrayList<Student>是不成立的 35 printl(s); 36 printll(s); 37 } 38 public static void printfx(ArrayList<?> a)//?是未限定引用数据类型 39 { 40 Iterator<?> i=a.iterator(); 41 while(i.hasNext()) 42 { 43 System.out.println(i.next()); 44 //System.out.println(i.next().length());//error,因为不确定类 45 } 46 } 47 public static void printt(ArrayList<Person> p) 48 { 49 Iterator<Person> i=p.iterator(); 50 while(i.hasNext()) 51 { 52 System.out.println(i.next().getName()); 53 } 54 } 55 //泛型限定上限 56 public static void printl(ArrayList<? extends Person> p) 57 { 58 Iterator<? extends Person> i=p.iterator(); 59 while(i.hasNext()) 60 { 61 System.out.println(i.next().getName()); 62 } 63 } 64 //泛型限定下限 65 public static void printll(ArrayList<? super Student> p) 66 { 67 Iterator<? super Student> i=p.iterator(); 68 while(i.hasNext()) 69 { 70 System.out.println(i.next()); 71 } 72 } 73 } 74 //定义一个Person类 75 class Person 76 { 77 private String name; 78 Person(String name) 79 { 80 this.name=name; 81 } 82 public String getName() 83 { 84 return name; 85 } 86 } 87 class Student extends Person 88 { 89 Student(String name) 90 { 91 super(name); 92 } 93 }
10、Map集合
Map
|--Hashtable:底层是哈希表数据结构,不可以存入空键值,该集合是线程同步的,在jdk1.0中。
|--HashMap:底层是哈希表数据结构,允许使用空键值和空值,该集合是不同步的,在jdk1.2中,效率高。
|--TreeMap:底层是二叉树数据结构,线程不同步,可以用于给map集合中的键进行排序。
实质上,Set集合底层就是使用了Map集合。
11、Collections集合:均是静态的方法。
12、Arrays集合:用于操作数组的工具类,方法均是静态的。