集合框架学习(二)

转载出处;http://m.blog.csdn.net/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方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值