转载出处;http://m.blog.youkuaiyun.com/article/details?id=44153345
三.List
1.概述:
元素是有序的,元素可以重复。
List本身是Collection接口的子接口,具备了Collection的所有方法。
2.List包括:
1)ArrayList:底层的数据结构是数组,线程不同步,ArrayList替代了Vector,查询元素的速度非常快。
2)LinkedList:底层的数据结构是链表,线程不同步,增删元素的速度非常快。(改变链表的地址)
3)Vector:底层的数据结构就是数组,线程同步的,Vector无论查询和增删都非常慢。被ArrayList替代了。
3.List特有方法:凡是可以操作角标的方法。
1)添加:
add(index,element) :在指定的索引位插入元素。Index是相应的位置,element是相应元素。
addAll(index,collection) :在指定的索引位插入一堆元素。collection是一个对象。
2)删除:
remove(index) :删除指定索引位的元素。返回被删的元素。
3)修改:
set(index,element):修改指定位置的元素。
4)查找:
get(index):通过角标获取元素。List集合因为角标有了自己的获取元素的方式:遍历。
subList(from,to):获取部分对象元素。(包含头,不包含尾)
listIterator():List特有的迭代器。
indexOf(obj) :获取指定元素第一次出现的索引位,如果该元素不存在返回-1;所以,通过-1,可以判断一个元素是否存在。
4.ListIterator:
1)概述:ListIterator是List集合特有的迭代器,是Iterator的子接口。
2)在迭代器时,只能用迭代器的方法操作元素。可是Iterator方法是有限的,只能对元素进行判断,取出,删除的操作。
如果想要其他的操作,如添加、修改等,就需要使用其子接口:ListIterrator。该接口只能通过List集合的ListIterator方法获取。
(代码 ListIteratorDemo.java):
import java.util.*;
class ListIteratorDemo
{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[] args)
{
ArrayList a = new ArrayList();
a.add("java01");
a.add("java02");
a.add("java03");
sop(a);
Iterator it = a.iterator();
while(it.hasNext())
{
Object obj = it.next();
if(obj.equals("java02"))
/* 在迭代时,不可以通过集合对象的方法操作集合中的元素。(a.add("java000");)
因为会发生ConcurrentModificationException异常。
导致的原因是:
集合引用和迭代器引用在同时操作元素,通过集合获取到对应的迭代器后,
在迭代中,进行集合引用的元素添加,迭代器并不知道,所以会出现异常情况。
*/
//a.add("java000");
it.remove();//将java02的引用从集合中删除了。
sop("obj= "+obj);
}
sop(a);
}
}
3)ListIterator特有的方法:
add(obj); 增加。
set(obj); 修改为obj。
hasPrevious(); 判断前面有没有元素。
previous(); 取前一个元素。
5.可变长度数组的原理:
当元素超出数组长度,会产生一个新数组,将原数组的数据复制到新数组中,再将新的元素添加到新数组中。
ArrayList:是按照原数组的50%延长。构造一个初始容量为 10 的空列表。
Vector:是按照原数组的100%延长。
6.枚举Enumeration:
枚举就是Vector特有的取出方式。
例如:
Vector v=new Vector();
for(Enumeration e=v.elements();e.hasMoreElements();)
{
System.out.println(e.nextElements());
}
7.LinkedList:
LinkedList:特有方法:
addFirst();
addLast();
getFirst();
getLast();获取元素,但不删除元素。如果集合中没有元素,会出现NoSuchElementException。
removeFirst();
removeLast();获取元素,但是元素被删除。如果集合中没有元素,会出现NoSuchElementException。
在JDK1.6出现了替代方法。
offerFirst();
offerLast();
peekFirst();
peekLast();获取元素,但不删除元素。如果集合中没有元素,会返回null。
pollFirst();
pollLast();获取元素,但删除元素。如果集合中没有元素,会返回null。
练习:(代码 LinkedListDemo.java):
//使用LinkedList模拟一个队列数据结构
//队列:先进先出
import java.util.*;
class LinkedListDemo
{
public static void main(String[] args)
{
DuiLie d = new DuiLie();
d.add("java01");
d.add("java02");
d.add("java03");
while(!d.isNull())
{
System.out.println(d.get());
}
}
}
class DuiLie
{
private LinkedList link;
DuiLie()
{
link = new LinkedList();
}
public void add(Object obj)
{
link.addFirst(obj);
}
public Object get()
{
return link.removeLast();
}
public boolean isNull()
{
return link.isEmpty();
}
}
8.练习题:
(代码 ArrayListDemo.java):
//去除ArrayList集合中的重复元素。
import java.util.*;
class ArrayListDemo
{
public static void main(String[] args)
{
ArrayList a = new ArrayList();
a.add("java01");
a.add("java02");
a.add("java03");
a.add("java01");
System.out.println(a);
System.out.println(quchu(a));
}
public static ArrayList quchu(ArrayList a)
{
ArrayList newa = new ArrayList();
Iterator it = a.iterator();
while(it.hasNext())
{
Object obj = it.next();
if(!newa.contains(obj))
newa.add(obj);
}
return newa;
}
}
(代码 ArrayListDemo2.java):
/*
将自定义对象作为元素存到ArrayList集合中,并去除重复元素。
比如:存人对象,同姓名同年龄,视为同一个人,为重复元素。
*/
import java.util.*;
class ArrayListDemo2
{
public static void main(String[] args)
{
ArrayList a = new ArrayList();
a.add(new Person("zhangsan",10));
a.add(new Person("lisi",11));
a.add(new Person("wangwu",12));
a.add(new Person("lisi",11));
//sop(a);
a = quchu(a);
Iterator it = a.iterator();
while(it.hasNext())
{
Object obj = it.next();
Person p = (Person)obj;
sop(p.getName()+"..."+p.getAge());
}
}
public static ArrayList quchu(ArrayList a)
{
ArrayList newa = new ArrayList();
Iterator it = a.iterator();
while(it.hasNext())
{
Object obj = it.next();
if(!newa.contains(obj))//contains依据的是equals方法。
newa.add(obj);
}
return newa;
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
class Person
{
private String name;
private int age;
Person(String name,int age)
{
this.name = name;
this.age = age;
}
//List集合判断元素是否相同,依据的是元素的equals方法。
public boolean equals(Object obj)
{
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
return this.name.equals(p.name) && this.age == p.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
/*
注意:
对于ArrayList集合,判断元素是否存在,或者删元素底层依据都是equals方法。
*/
四.Set
1.理解:
无序(存入和取出顺序有可能不一致),不可以存储重复元素。必须保证元素唯一性。
Set集合的功能和Collection是一致的。Set接口取出方式只有一种,迭代器。
2.分类:HashSet和TreeSet。
1)、HashSet:
底层数据结构是哈希表,线程是不同步的(线程不安全)。无序,高效。存取速度快。
HashSet集合保证元素唯一性:
通过元素的hashCode和equals方法完成的。
如果元素的hashCode值相同,才继续判断元素的equals是否为true。
如果元素的hashCode值不同,那么不判断equals,从而提高对象比较的速度。
(复写hashCode和equals)
public int hashCode()
{
return name.hashCode()+age;
}
public boolean equals(Object obj)
{
if(!(obj instanceof Person))
return false;
Person p = Person(obj);
return this.name.equals(p.name) && this.age==p.age;
}
下面用代码体现:
(代码 HashSetDemo.java):
/*
往HashSet集合中存入自定义对象。
姓名和年龄相同为同一个人,重复元素。
*/
import java.util.*;
class HashSetDemo
{
public static void main(String[] args)
{
HashSet hs = new HashSet();
hs.add(new Person("a1",11));
hs.add(new Person("a3",13));
hs.add(new Person("a1",11));
hs.add(new Person("a2",12));
Iterator it = hs.iterator();
while (it.hasNext())
{
Person p = (Person)it.next();
System.out.println(p.getName()+"..."+p.getAge());
}
}
}
class Person
{
private String name;
private int age;
Person(String name,int age)
{
this.name = name;
this.age = age;
}
public int hashCode()
{
return name.hashCode()+age;
}
public boolean equals(Object obj)
{
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
return this.name.equals(p.name) && this.age==p.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
//注意:
//对于HashSet集合,判断元素是否存在(contains),或者删除元素(remove),
//底层依据的是hashCode方法和equals方法。
2)、TreeSet:
可以对Set集合中的元素进行排序。默认按照字母的自然排序。底层数据结构是二叉树。线程是不同步的(线程不安全)。
保证元素唯一性的依据:compareTo方法return 0。
TreeSet的第一种排序方式:
如果元素不具备比较性,在运行时会发生ClassCastException异常。
所以需要元素实现Comparable接口,强制让元素具备比较性,复写compareTo方法。
这种方式也称为元素的自然顺序,或者叫做默认顺序。
下面用代码体现:
(代码 TreeSetDemo.java):
/*
需求:
往TreeSet集合中存储自定义对象学生。
想按照学生的年龄进行排序。
记住:排序时,当主要条件相同时,一定要判断一下次要条件。
*/
import java.util.*;
class TreeSetDemo
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet();
ts.add(new Student("lisi01",11));
ts.add(new Student("lisi03",13));
ts.add(new Student("lisi02",12));
ts.add(new Student("lisi01",11));
ts.add(new Student("lisi0002",12));
Iterator it = ts.iterator();
while (it.hasNext())
{
Student stu = (Student)it.next();
System.out.println(stu.getName()+"::"+stu.getAge());
}
}
}
class Student implements Comparable//该接口强制让学生具备比较性。
{
private String name;
private int age;
Student(String name,int age)
{
this.name = name;
this.age = age;
}
public int compareTo(Object obj)
{
if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student s = (Student)obj;
if(this.age>s.age)
return 1;
if(this.age==s.age)
return this.name.compareTo(s.name);
return -1;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
TreeSet的第二种排序方式:
当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让容器自身具备比较性。
在集合初始化时就有了比较方式。定义一个比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。
让集合自身具备比较性,需要定义一个实现了Comparator接口的比较器,并覆盖compare方法,并将该类对象作为实际参数传递给TreeSet集合的构造函数。
第二种方式较为灵活。
下面用代码体现:
(代码 TreeSetDemo2.java):
import java.util.*;
class Student implements Comparable
{
private String name;
private int age;
Student(String name,int age)
{
this.name = name;
this.age = age;
}
public int compareTo(Object obj)
{
if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student s = (Student)obj;
if(this.age>s.age)
return 1;
if(this.age==s.age)
return this.name.compareTo(s.name);
return -1;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
class TreeSetDemo2
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet(new MyCompare());
ts.add(new Student("lisi01",11));
ts.add(new Student("lisi03",13));
ts.add(new Student("lisi02",12));
ts.add(new Student("lisi01",11));
ts.add(new Student("lisi0002",12));
Iterator it = ts.iterator();
while (it.hasNext())
{
Student stu = (Student)it.next();
System.out.println(stu.getName()+"::"+stu.getAge());
}
}
}
class MyCompare implements Comparator
{
public int compare(Object o1,Object o2)
{
Student s1 = (Student)o1;
Student s2 = (Student)o2;
int num = s1.getName().compareTo(s2.getName());
if(num==0)
{
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
/*
if(s1.getAge()>s2.getAge())
return 1;
if(s1.getAge()==s2.getAge())
return 0;
return -1;
*/
}
return num;
}
}
3.知识总结(需要注意的知识点):
对于ArrayList集合,判断元素是否存在,或者删元素底层依据都是equals方法。
对于HashSet集合,判断元素是否存在,或者删除元素,底层依据的是hashCode方法和equals方法。