Java 集合Collection(一)
泛型
1, JDK5 新特性,默认情况表示Object类型,也就是所有类型。它把明确类型的工作推迟到了创建对象或者调用方法才去明确。
这样做的好处:
1, 解决了隐藏的问题,优化了程序设计。
2, 把运行期的问题提前到了编译期。
3, 避免了强制类型转换。
2, 应用场景:
常见在集合中,API中标记有<>括号,就表示需要使用泛型。
增强for
1, 增强for循环是JDK5新特性,出现是为了替代迭代器,底层封装了迭代器。
2, 用增强for之前最好先判断对象不为null, 再遍历。
//底层封装了迭代器,在用迭代器遍历的时候通过集合修改集合中的元素 ArrayList<String> arraylist=new ArrayList<String>(); arraylist.add("hello"); arraylist.add("world"); arraylist.add("java"); for(String s: arraylist){ if("hello".equals(s)){ arraylist.add("Android"); } } //java.lang.ConcurrentModificationException 并发修改异常
//集合中只能存放引用类型,而迭代器是依赖集合而存在 ArrayList<String> arraylist=new ArrayList<String>(); arraylist.add("hello"); arraylist.add("world"); arraylist.add("java"); arraylist=null; for(String s: arrlist){ System.out.println(s); } //java.lang.NoPointerException 空指针
List
1, List的特点:
Collection
|-----List :元素有序(存入和取出顺序一致),可重复。
2, List的特有功能 :
添加功能:
add(int index,Object obj)
删除功能:
remove(int index)
修改功能:
set(int index,Object obj)
获取功能:
get(int index)
3, List的子类 :
List
|-----ArrayList
底层数据结构是数组,增删慢,查询快,线程不同步(不安全),效率高。
注意:contains方法依赖于equals()方法,如果需要判断对象有的成员或者内容是否相同需要重写equals()方法。
|-----Vector
底层数据结构是数组,增删慢,查询快,线程同步(安全),效率低。JDK1.0版本的功能,已经被ArrayList替代。
特有功能 :
添加元素:
public void addElement(Object obj) >> add(Object obj)
获取元素:
public Object EelmentAt(int index) >> get(int index)
public Enumeration element() >> iterator()
hasMoreElements >> hasNext()
nextElement >> next()
长度功能 :
public int size()
|----Stack
是一个栈数据结构。
特点:数据先进后出(存、取)。
功能:
添加功能:
public Object push(Objcet obj):添加元素,并将元素本身返回。
获取功能:
public Object pop():移除栈顶元素,并返回该元素。
判断功能:
public boolean empty():测试元素是否为空。
|-----LinkedList
底层数据结构是双向循环链表,增删快,查询慢,线程不同步(不安全),效率高。
由于是链表,操作开头和结尾比较简单,提高了增加、删除、获取开头和获取结尾。
特有功能:
添加元素:
void addFirst(Object e)
void addLast(Object e)
删除元素:
removeFist()
removeLast()
获取元素:
getFist()
getLast()
4, ListIterator :
1,可以逆向遍历,前提是正向遍历之后,因只有正向遍历完成之后,指针在末尾。(意义不大)
逆向遍历示例:
//逆向遍历 List<String> list=new ArrayList<String>(); list.add("hello"); list.add("world"); list.add("java"); //正向迭代 Iterator<String> it=list.iterator(); while(it.hasNext()){ String s=it.next(); System.out.println(s); } //此时正向迭代结束,指针在结尾 //逆向迭代 ListIterator<String> lit=list.listIterator(); while(lit.hasPrevious()){ String s2=lit.previous(); System.out.println(s2); }
2,可以解决并发修改的异常问题。
并发修改异常:在用迭代器遍历集合的时候,通过集合修改了集合中的元素。
java.lang.ConcurrentModificationException
解决方案:
a : 通过列表迭代器遍历集合,通列表迭代器修改集合元素。
这个时候元素添在查处的元素,而不是在末尾处添加。
//通过列表迭代器修改 List<String> list=new ArrayList<String>(); list.add("hello"); list.add("world"); list.add("java"); //用list迭代器进行迭代,用list迭代器修改元素。 ListIterator<String> lit=list.listIterator(); while(lit.hasNext()){ String s=lit.next(); if("world".equals(s)){ lit.add("Android"); } }
b : 通过集合遍历,通过集合修改集合(普通for)
这个时候是在集合末尾处添加。
//通过普通for循环添加 List<String> list =new ArrayList<String>(); list.add("hello"); list.add("world"); list.add("java"); for(int i =0;i<list.size();i++){ String s=list.get(i); if("world".equals(s)){ list.add("Android"); } }
案例:
用LinkedList模拟栈数据结构。
自定义栈
Set
1, Set的特点:
Collection
|-----Set :元素唯一,无序(存入和取出顺序不一致)。
|-----HashSet
底层数据结构是哈希表。
哈希表依赖hashCode()和equals()两个方法。
如何保证元素唯一性?
先执行hashCode()的值进行比较:
相同:
执行equals()方法比较成员值是否相同。
true:对象成员值相同,那么就不添加到集合中。
false:对象成员值不相同,添加到集合中。
不同:添加到集合中
注意:
如果汲步到hash这种数据结构,就要明白,需要重写hashCode()和equals()方法。
重写hashCode()是为了执行到equals(),优化它,是为了提高效率。
重写euals()是为了比较成员的内容。
|-----TreeSet
有序(按照某种规则顺序),元素唯一。
底层数据结构是二叉树。
可以根据自然排序和比较器排序(创建Set时提供的Comparator进行排序)对集合中的元素进行排序。
构造方法:
TreeSet()
构造一个空Set,该Set根据自然数对数据进行排序。
如何保证元素唯一?
根据返回值是否为0;
如何进行排序?
自然排序(元素具备比较性)
被装载的对象实现Comparable接口。
比较器排序(集合具备比较性)
创建TreeSet集合的时候,传递Comparator接口的子类对象。
示例:
//如果一个方法是抽象类或者接口的时候,只调用一次的情况,用匿名内部类实现。 TreeSet<Student> ts=new TreeSet<Student>(new Comparator<Student>(){ public int compare(Student s1,Student s2){ int num=s1.getAge()-s2.getAge(); int num2=num==0?s1.getName().compareTo(s2.getName()):num; return num2; } }); //----------------------------------------------------------------------------------------------------------------------------------- //等价于此 Comparator<Student> comparator=new MyComparator(); TreeSet<Student> ts=new TtreeSet<Student>(comparator); public class MyComparator implements Comparator<Student>{ @override int num=s1.getAge()-s2.getAge(); int num2=num==0?s1.getName().compareTo(s2.getName()):num; return num2; } //---------------------------------------------------------------------------------------------------------------------------------- // 创建学生对象 Student s1 = new Student("baigujing", 20); Student s2 = new Student("zixixianzi", 22); Student s3 = new Student("guanyinjiejie", 18); Student s4 = new Student("tangseng", 20); Student s5 = new Student("bailongma", 20); Student s6 = new Student("niumowang", 24); Student s7 = new Student("taibaijinxing", 55); Student s8 = new Student("change", 18); Student s9 = new Student("change", 18); Student s10 = new Student("zixixianzi", 22); // 添加元素 ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); ts.add(s6); ts.add(s7); ts.add(s8); ts.add(s9); ts.add(s10); // 遍历 for (Student s : ts) { System.out.println(s.getName() + "---" + s.getAge()); }