码迷,mamicode.com
首页 > 编程语言 > 详细

黑马程序员----java基础---详解Collection集合

时间:2015-06-09 10:02:48      阅读:174      评论:0      收藏:0      [点我收藏+]

标签:java   集合   list   set   迭代器   

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

1:集合(Collection)

(1)集合的由来?
我们学习的是Java -- 面向对象 -- 操作很多对象 -- 对象需要存储 -- 容器(数组和StringBuffer) -- 数组
而数组的长度固定,所以不适合做变化的需求,Java就提供了集合供我们使用。
(2)集合和数组的区别?
A:长度区别
数组固定
集合可变
B:内容区别
数组可以是基本类型,也可以是引用类型
集合只能是引用类型(对象)
C:元素内容
数组只能存储同一种类型
集合可以存储不同类型(其实集合一般存储的也是同一种类型)
(3)集合的继承体系结构?
由于需求不同,Java就提供了不同的集合类。这多个集合类的数据结构不同,但是它们都是要提供存储和遍历功能的,
我们把它们的共性不断的向上提取,最终就形成了集合的继承体系结构图。

Collection
|--List
|--ArrayList
|--Vector
|--LinkedList
|--Set
|--HashSet
|--TreeSet
(4)Collection的功能概述
A:添加功能
boolean add(Object obj);添加一个元素
boolean addAll(Collection c);添加一个集合元素
B:删除功能
void clear();移除所有元素
boolean remove(Object o);移除一个元素
boolean removeAll(Collection c);移除一个集合里的所有元素
C:判断功能
boolean contains(Object o);判断集合中是否包含指定的元素
boolean containsAll(Collection c);判断集合中是否包含指定的集合
boolean isEmpty();判断集合是否为空。
D:获取功能
Iterator<E> iterator();迭代器,用来遍历。
E:长度功能
int size();获取元素的个数集合的长度
F:交集(了解)
boolean retainAll(Collection c):判断两个集合是否有交集
假设有两个交集,A,B.调用交集方法时返回值表示A是否发生改变,如果有交集A会变成交集内容。
G:把集合转数组(了解)
Object[] toArray();
(5)Collection集合的遍历
A:把集合转数组(了解)
Collection c=new ArrayList();
c.add("hello");
Object[] objs=c.toArray();
B:迭代器(集合专用方式)
//创建集合对象
Collection c=new ArrayList();

//创建并添加元素
c.add("hello");
c.add("world");

//使用迭代器来遍历
Iterator it=c.iterator();//实际返回的是子类对象,这里是多态

while(it.hasNext()){
String s=(String) it.next();//这里it是Object对象,要想获得字符串,需要向下强转。
System.out.println(s);
}

//上面的while循环可以用for循环来替代
/*
for(Iterator it=c.iterator();it.hasNext();){
System.out.println(it.next());
}
*/
(6)迭代器
A:是集合获取元素的一种遍历方式。
B:是依赖于集合而存在的。
C:迭代器的原理和源码。
a:为什么定义为一个接口而不是实现类?
b:看了看迭代器的内部类实现。
(7)Collection集合的案例(遍历方式 迭代器)
集合的操作步骤:
A:创建集合对象
B:创建元素对象
C:把元素添加到集合
D:遍历集合

A:存储字符串并遍历
B:存储自定义对象并遍历
public class Student {
private String name;
private int age;

public Student(){}

public Student(String name,int age) {
this.name = name;
this.age = age;
}

//getXxx()/setXxx()
}

import java.util.Collection;
import java.util.ArrayList;
import java.util.Iterator;

public class StudentDemo {
public static void main(String[] args) {
//创建集合对象
Collection c = new ArrayList();

//创建学生对象
Student s1 = new Student("林青霞",27);
Student s2 = new Student("风清扬",30);
Student s3 = new Student("刘意",30);
Student s4 = new Student("武鑫",25);
Student s5 = new Student("刘晓曲",16);

//添加元素
c.add(s1);
c.add(s2);
c.add(s3);
c.add(s4);
c.add(s5);

//遍历集合
Iterator it = c.iterator();
while(it.hasNext()) {
Student s = (Student)it.next();
System.out.println(s.getName()+"---"+s.getAge());
}
}
}


2:集合(List)(掌握)
(1)List是Collection的子接口
特点:有序(存储顺序和取出顺序一致),可重复。
(2)List的特有功能:(自己补齐)
A:添加功能
void add(int index,Object element):在指定位置添加元素
B:删除功能
Object remove(int index):根据索引删除元素,返回被删除的元素。
C:获取功能
Object get(int index);获取指定位置的元素
D:迭代器功能(列表迭代器)
ListIterator listIterator();List集合特有的迭代器。
E:修改功能
Object set(int index,Object element):根据索引修改元素,返回被修饰的元素
(3)List集合的特有遍历功能
A:由size()和get()结合。
B:代码演示
//创建集合对象
List list = new ArrayList();

//创建并添加元素
list.add("hello");
list.add("world");
list.add("java");

//迭代器遍历集合
Iterator it = list.iterator();
while(it.hasNext()) {
String s =(String) it.next();
System.out.println(s);
}
System.out.println("----------");

/*
List特有的size和get方法结合来遍历集合的方法
for(int x=0; x<list.size(); x++) {
String s =(String) list.get(x);
System.out.println(s);
}*/
(4)列表迭代器的特有功能;(了解)ListIterator
ListIterator是List集合特有的功能,可以逆向遍历,但是要先正向遍历,所以无意义,基本不使用。通常还是使用Iterator来遍历
(5)(面试题)并发修改异常(ConcurrentModificationException)
A:出现的现象
迭代器遍历集合,集合修改集合元素,而迭代器是依赖于集合存在的,集合改变时,迭代器并不知道。所以报错。
B:原因
迭代器是依赖于集合的,而集合的改变迭代器并不知道。
C:解决方案
a:迭代器遍历,迭代器修改(ListIterator)
元素添加在刚才迭代的位置
//方法一:用迭代器来修改元素
ListIterator lit=list.listIterator();
while(lit.hasNext()){
String s=(String)lit.next();
if("world".equals(s)){
lit.add("javaee");
}
}
System.out.println(list);
b:集合遍历,集合修改(size()和get())
元素添加在集合的末尾
//方法二,用普通for循环遍历
for(int x=0;x<list.size();x++){
String s=(String)list.get(x);
if(str.equals(s)){
list.add("javaee");
}
}
System.out.println(list);
(6)常见数据结构
A:栈 先进后出(子弹夹的例子)
B:队列 先进先出(火车买票排队的例子)
C:数组 查询快,增删慢
D:链表 查询慢,增删快
(7)List的子类特点(面试题)
ArrayList
底层数据结构是数组,查询快,增删慢。
线程不安全,效率高。
Vector
底层数据结构是数组,查询快,增删慢。
线程安全,效率低。
LinkedList
底层数据结构是链表,查询慢,增删快。
线程不安全,效率高。

到底使用谁呢?看需求?
分析:
要安全吗?
要:Vector(即使要,也不使用这个,后面再说)
不要:ArrayList或者LinkedList
查询多;ArrayList
增删多:LinkedList

什么都不知道,就用ArrayList。

3:List的子类(掌握)
(1)List的子类特点
ArrayList:
底层数据结构是数组,查询快,增删慢
线程不安全,效率高
Vector:
底层数据结构是数组,查询快,增删慢
线程安全,效率低
LinkedList:
底层数据结构是链表,查询慢,增删快
线程不安全,效率高
(2)ArrayList
A:没有特有功能需要学习
B:案例
a:ArrayList存储字符串并遍历
b:ArrayList存储自定义对象并遍历
(3)Vector
A:有特有功能
a:添加
public void addElement(E obj) -- add()
b:获取
public E elementAt(int index) -- get()
public Enumeration<E> elements() --  iterator()
B:案例
a:Vector存储字符串并遍历
b:Vector存储自定义对象并遍历
(4)LinkedList
A:有特有功能
a:添加
public void addFirst();在开头添加
public void addLast();在末尾添加,和add的功能一样
b:删除
public Object removeFirst();删除第一个元素并返回删除的这个元素
public Object removeLast();
c:获取
public Object getFirst();获取第一个元素
public Object getLast()
B:案例
a:LinkedList存储字符串并遍历
b:LinkedList存储自定义对象并遍历
4,Set集合(理解)
(1)Set集合的特点
无序,唯一
(2)HashSet集合(掌握)  无序,唯一
A:底层数据结构是哈希表(是一个元素为链表的数组)
B:为了保证元素唯一,哈希表底层依赖两个方法:hashCode()和equals()
 执行顺序:
首先比较哈希值是否相同
相同:继续执行equals()方法
返回true:元素重复了,不添加
返回false:直接把元素添加到集合
不同:就直接把元素添加到集合
C:如何保证元素唯一性的呢?
由hashCode()和equals()保证的,当集合存储对象时,需要重写hashCode()和equals(),这个重写可以自动生成的
D:开发的时候,代码非常的简单,自动生成即可。
E:HashSet存储字符串并遍历
F:HashSet存储自定义对象并遍历(对象的成员变量值相同即为同一个元素):
这个时候要在类中重载hasCode()和equals()方法,而重载hasCode()和equals()方法是可以自动生成的。alt+shift+s
代码演示
//创建HashSet集合对象
HashSet<Student> hash=new HashSet<Student>();

//创建需要存储的对象
Student s1=new Student("李晨",25);
Student s2=new Student("邓超",27);
Student s3=new Student("郑凯",24);
Student s4=new Student("陈赫",24);
Student s5=new Student("李晨",25);
Student s6=new Student("李晨",23);

//位集合添加元素
hash.add(s1);
hash.add(s2);
hash.add(s3);
hash.add(s4);
hash.add(s5);
hash.add(s6);

//用增强for循环来遍历集合
for(Student s: hash){
System.out.println(s.getName()+"---"+s.getAge());
}
(3)TreeSet集合
A:底层数据结构是红黑树(是一个自平衡的二叉树)(有图解)
B:保证元素的排序方式
a:自然排序(元素所属的类具备比较性)
让元素所属的类实现Comparable接口,
如果存储的是对象,需要对象所属的类重写compareTo()方法。
自然排序的比较是依赖于元素的compareTo()方法,而这个方法是定义在Comparable
里面的,所以要想重写该方法,就必须先实现Comparable接口,而这个接口表示的就是自然排序。
b:比较器排序(集合具备比较性)
让集合构造方法接收Comparator的实现类对象
C:唯一性:根据比较的返回值,如果为0就不添加。

案例:用自然排序和比价器排序来以年纪的大小来遍历集合
1,自然排序:让元素所属的类实现Comparable接口,排序规则定义在Student类中
public class Student implements Comparable<Student> {
//定义私有变量,定义构造方法,定义set和get方法。
@Override//重写Comparable中的compareTo方法
public int compareTo(Student s) {
//这里返回什么其实要根据我们的排序规则来定
//主要条件:按照年纪来排序
int num=this.age-s.age;
//次要条件:姓名,因为年龄一样姓名也相同时才是同一个元素。
int num2=num==0?this.name.compareTo(s.name):num;
return num2;
}
}

public static void main(String[] args) {
//创建TreeSet集合对象,用来存储自定义对象
TreeSet<Student> tr=new TreeSet<Student>();
//创建对象
Student s1=new Student("xiaoming",22);
Student s2=new Student("xiaoming",23);
Student s3=new Student("xiaohua",22);
//添加元素
tr.add(s1);
tr.add(s2);
tr.add(s3);
//遍历集合
for(Student s:tr){
System.out.println(s.getName()+"---"+s.getAge());
}
}

5:比较器排序:让TreeSet集合的构造方法接收Comparator的实现类对象,通过匿名内部类把比较规则定义在main方法中。
public class Student implements Comparable<Student> {
//定义私有变量,定义构造方法,定义set和get方法。
}
public static void main(String[] args) {
//用匿名内部类把Comparator接口的实现类作为参数传入TreeSet的构造方法中。
TreeSet<Student> tr=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;
}
});
//创建对象
Student s1=new Student("xiaoming",22);
Student s2=new Student("xiaoming",23);
Student s3=new Student("xiaohua",22);
//添加元素
tr.add(s1);
tr.add(s2);
tr.add(s3);
//遍历集合
for(Student s:tr){
System.out.println(s.getName()+"---"+s.getAge());
}
}


(4)案例:
A:获取10个1-20之间的无重复的随机数
//创建随机数对象
Random r=new Random();
//创建集合对象,用来存储随机数
HashSet<Integer> ts=new HashSet<Integer>();
//为集合添加元素
while(ts.size()<10){
//获取1-20之间的随机数
int num=r.nextInt(20)+1;
ts.add(num);
}
//遍历集合
for(int i:ts){
System.out.println(i);
}

黑马程序员----java基础---详解Collection集合

标签:java   集合   list   set   迭代器   

原文地址:http://blog.csdn.net/qiushi_1990/article/details/46418827

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!