黑马程序员技术交流社区
标题:
List与Set集合的小结
[打印本页]
作者:
谭立文
时间:
2012-10-8 11:34
标题:
List与Set集合的小结
List和Set都是Collection的子接口
Collection
|-----List (有序,可重复)
| |-----Vector 特点:线程安全
| |-----ArrayList 特点:不具线程安全,底层用数组来实现的,有序,适合存放查询,修改比较频繁的操作。
| |-----LinkedList 特点:不具线程安全,底层用链表来实现,有序,适合对元素的增删操作。
|
|-----Set (不可重复)
| |-----HashSet 此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。
|-----LinkedHashSet 具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现.
|-----TreeSet
总结之List集合:
由于Vector是线程安全的,同步的,在一般情况下,为了考虑到程序运行的效率问题,很多时候我们都选择使用ArrayList,Vector渐渐的也被ArrayList所取代。
关于继承了AbstractList类,特有迭代器ListIteraotr的一点小细节:
package com.wenfengkeji.collection;
import java.util.ArrayList;
import java.util.ListIterator;
public class ArrayListDemo {
public static void main(String[] args) {
ArrayList<Person> al = new ArrayList<Person>();
al.add(new Person("a", 18));
al.add(new Person("b", 16));
al.add(new Person("c", 20));
al.add(new Person("d", 21));
ListIterator<Person> lt = al.listIterator();
while(lt.hasNext())
{
Person p = lt.next();
if(p.getName().equals("a"))
{
//al.add(new Person("ok", 21)); //出错
System.out.println(al.size());
lt.remove(); //若remove在add之后抛IllegalStateException
lt.add(new Person("ok", 21));
/*
* lt.remove();
* 从列表中移除由 next 或 previous 返回的最后一个元素(可选操作)。
* 对于每个 next 或 previous 调用,只能执行一次此调用。只有在最后一次调用 next
* 或 previous 之后,尚未调用 ListIterator.add 时才可以执行该调用。
*/
System.out.println(al.size());
}
}
System.out.println(al);
}
}
---------------------------------------------------------------------------------------------------------
总结之HashSet、LinkedHashSet集合:
HashSet集合的主要特点是:不保证顺序(若用LinkedHashSet可以做到按添加时的顺序),因为底层是用Map来实现,唯一性:1.hashCode、equals
元素被添加到 HashSet集合的过程:
首先被添加对象调用该对象的hashCode方法获得hashCode,根据该hashCode寻找HashSet集合所在的内存单元,若两个不同的对象具有相同的hashCode则会调用
equals方法进一步进行比较,具体的比较方式可以自己去实现,默认的比较的是两个对象的引用,若引用相同则不会被添加到集合中,一般我们会自己重写hashCode方法和equlas方法来避免重复添加的问题,因为hashCode的默认计算方式是根据对象的内存地址信息来计算出的,是一个native方法。
若没有hash冲突则该对象就直接被添加到集合当中了,不会再调用equlas。
值得注意的是若某个类依据其某个或某些Filed重写了hashCode方法,在该对象被添加到集合中之后,若修改了该对象参与计算hashCode值得字段,则该对象将不能够再通过
集合的public boolean remove(Object o)方法从集合当中移除了,因为HashSet集合(这种数据结构)就是依靠计算元素的hashCode值来在集合所开辟的那段内存单元中查找、定位到存放元素的位置的,若出现这种情况就发生内存泄露,应该特别注意。
----------------------------------------------------------------------------------------------------------
总结之TreeSet集合:
TreeSet集合也是属于Set集合体系的成员之一,该集合的主要功能是可以按一定规则对元素(对象)在添加到集合的过程中就对其进行排序。
其底层是用二叉树这种数据结构来实现的。
想要添加到集合中的元素排序,有两种实现方式
第一种是让元素具有可比较性,即实现java.lang.Comparable接口
实现int compareTo(T o)方法,若返回值为0 表示当前正在考虑被添加的元素与被比较的元素具有相同的意义,将不会被添加到集合当中,若 < 0 表示当前正在考虑被添加的元素在逻辑上应该排在被比较元素之后,若 > 0,则正在考虑被添加的元在当前被比较元素之前。
第二种是让集合自身具有某种可比较性规则,即将某个实现了比较器Compartor的类传递给集合,让集合具有这种比较规则。
实现public int compare(Object o1, Object o2);这个与compareTo(Object obj)类似。
关于第二种方式的需求分析:因为有时时候被人给你了一个类像java.lang.String 已经将该方法实现了,我在添加String元素到集合当中时我不想用String默认的比较方式,这个时候
就只能使用第二种了。
package com.wenfengkeji.collection;
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetDemo {
/*
* TreeSet 能够保证数据的唯一性,并能够对元素进行排序
* 保证唯一性的标准:既不是依靠hashcode也不依靠equlas方法
* 而是根据compareTo方法的返回值
* 若为0表示有重复的不添加
* 若为-1排在当前this所对应的元素之后
* 若为1排在当前this所对应的元素之前
*
* 需求:按照年龄的从小到大顺序进行排序
* 若年龄相同按照姓名
*/
public static void main(String[] args) {
comparator();
}
/*
* 让集合自身具有比较性
*/
public static void comparator() {
TreeSet<Person> ts = new TreeSet<Person>(new Comparator(){
@Override
public int compare(Object o1, Object o2) {
Person p1 = (Person)o1;
Person p2 = (Person)o2;
int temp = p1.getAge() - p2.getAge();
return temp == 0 ? p1.getName().compareTo(p2.getName()):temp;
}
});
ts.add(new Person("aa",21));
ts.add(new Person("ca",19));
ts.add(new Person("aa",22));
ts.add(new Person("za",19));
for(Person p : ts)
{
System.out.println(p);
}
}
public static void comparable() {
TreeSet<Person> ts = new TreeSet<Person>();
ts.add(new Person("aa",21));
ts.add(new Person("ca",19));
ts.add(new Person("aa",22));
ts.add(new Person("za",19));
for(Person p : ts)
{
System.out.println(p);
}
}
}
class Person implements Comparable
{
private String name;
private int age;
public Person(String name,int age)
{
this.name = name;
this.age = age;
}
public String toString()
{
return this.name + ":" + this.age;
}
@Override
public int compareTo(Object o) {
if(o == null)
return 0;
if(!(o instanceof Person))
throw new ClassCastException();
Person p = (Person)o;
int temp = this.age - p.age;
return temp == 0 ? this.name.compareTo(p.name):temp;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2