您的位置:首页 > 职场人生

黑马程序员_JAVA学习日记_JAVA中API:集合框架1(Collection,List,Set及其子类和迭代器的应用)

2012-08-13 23:14 1176 查看
黑马程序员-学习日记

黑马程序员_JAVA中集合框架1(Collection,List,Set及其子类和迭代器的应用)

------- android培训java培训、期待与您交流! ----------

一:集合是用于存储对象的一个工具。

集合和数组的特点:

1.相同点:

集合和数组都一个容器。

2.集合:

1,可以存储对象,只能存储对象。

2,集合的长度的是可变的。

3.数组:

1,可以存储对象,也可以存储基本数据类型值。

2,数组长度的是固定的。

注意:CollectionDemo.java 使用了未经检查或不安全的操作。注意:要了解详细信息,请使用 -Xlint:unchecked 重新编译。

Java编译器认为该成存在安全隐患。友情提示:但并不是编译失败,所以可以不用理会。

其实是因为类型的原因导致的,用了泛型以后,就没有该提示了。

二:集合中的一般方法:

importjava.util.*;

classCollectionDemo{

public static void main(String[] args){

Collection coll = new ArrayList();//创建了一个集合对象.也就是一个容器。

//添加元素。add();

coll.add("abc1");

coll.add("abc2");

coll.add("abc3");

System.out.println("集合的元素:"+coll);

//删除元素。

boolean b =coll.remove("abc2");

System.out.println("b="+b);

//获取集合的长度。

int size = coll.size();

System.out.println("size="+size);

//清除集合中的所有元素。

coll.clear();

//判断:

boolean b = coll.isEmpty();//其实内部依据的是size()方法。如果size()=0,就返回true。

System.out.println("b="+b);

boolean b=coll.contains("abc1");

System.out.println("b="+b);

//简单的获取集合所有元素。直接将集合的元素打印到控制台。

System.out.println("操作后的集合:"+coll);

}

}

三:Collection中带All的方法用法集合:

import java.util.*;

class CollectionDemo2 {

public static void main(String[] args) {

Collection coll = new ArrayList();//创建了一个集合对象.也就是一个容器。

coll.add("abc1");

coll.add("abc2");

coll.add("abc3");

System.out.println("集合的元素:"+coll);

Collection co2 = new ArrayList();

co2.add("abc3");

co2.add("abc2");

co2.add("abc1");

co2.add("abc4");

Collection co3 = new ArrayList();

co3.add("abc7");

co3.add("abc8");

//添加一堆元素。

//coll.addAll(co2);//将co2中的元素添加到coll集合中。[abc1, abc2, abc3, abc5, abc]

//判断一堆元素是否存在。

boolean b = coll.containsAll(co3);

System.out.println("b="+b);

//删除一堆元素。

boolean b1 =coll.removeAll(co3);//removeAll会将coll中包含的和co3相同的元素删除。

System.out.println("b1="+b1);

//获取两个集合的交集。

boolean b=coll.retainAll(co2);//retainAll会将coll和co2中相同的元素保留在coll中。

//所以coll中存储就是交集的元素。当coll集合中的元素变化时,retainAll方法返回true。

//当coll集合中的元素本身就是交集元素,不发生变化。那么返回false。

System.out.println("b="+b);

System.out.println(coll);

}

}

四:Collection集合中对元素的获取方法:

import java.util.*;

class IteratorDemo{

public static void main(String[] args) {

Collection coll = new ArrayList();

coll.add("abc1");

coll.add("abc2");

coll.add("abc3");

//只要是Collection集合体系,迭代器就是通用取出方式。

/*

Iterator it = coll.iterator();

while(it.hasNext()){

System.out.println(it.next());

}

*/

for(Iterator it = coll.iterator() ;it.hasNext(); ){

System.out.println(it.next());

}

}

}

五:LinkedList的特有方法:

1:addFirst();

addLast();

在jdk1.6以后被

offerFirst();

offerLast();替代

2:获取元素,集合的长度不改变:

如果集合中没有元素,那么该方法会发生异常NoSuchElementException

getFirst():

getLast();

在jdk1.6以后被

peekFirst();

peekLast();替代

如果集合元素没有,该方法不会抛出异常,而是返回null。

3:获取元素,但是该元素会被删除出集合,集合的长度会改变:

如果集合中没有元素,那么该方法会发生异常NoSuchElementException

removeFirst():

removeLast();

在jdk1.6以后被:

pollFirst();

pollLast();替代

如果集合元素没有,该方法不会抛出异常,而是返回null。

import java.util.*;

class LinkedListDemo {

public static void main(String[] args) {

LinkedList link = new LinkedList();

link.addFirst("abc1");

link.addFirst("abc2");

link.addFirst("abc3");

link.addFirst("abc4");

System.out.println(link.getFirst());

System.out.println(link.removeFirst());

System.out.println(link);

while(!link.isEmpty()){

System.out.println(link.removeFirst());

}

}

}

六:List集合中常见的共性方法:List:该容器的元素是有序的(存储的顺序和取出的顺序一致) 该集合中的元素都有索引(角标).该集合可以存储重复的元素。

1,添加元素:add();

2,删除元素:remove();

3,修改元素: set();

4,获取元素:get();

import java.util.*;

class ListDemo{

public static void main(String[] args){

List list = new ArrayList();

list.add("abc1");

list.add("abc2");

list.add("abc3");

System.out.println("原集合:"+list);

//添加功能。在指定位置插入元素。

list.add(1,"haha");//在1索引为插入元素 haha.其他元素依次顺延。

//按照指定索引删除元素。会返回被删除的元素。

System.out.println("remove(1):"+list.remove(1));

//最指定位置的元素进行修改。会返回被修改掉的元素.

System.out.println("set(0,kk)="+list.set(0,"kk"));

//通过索引获取指定元素。

System.out.println("get(1):"+list.get(1));

//通过元素获取到第一次出现位置。

System.out.println("indexOf(abc2)="+list.indexOf("abc2"));

//根据头尾角标获取子列表。

List newList = list.subList(0,2);//全取list.subList(0,list.size());

System.out.println("自列表是:"+newList);

//通过List特有的方式,获取集合中所有的元素。

for(int x=0; x<list.size(); x++){

System.out.println(list.get(x));

}

System.out.println("操作后:"+list);

}

}

七:List:有序,可重复,有索引:

|--ArrayList:底层数据结构是数组结构。线程不安全的。所以ArrayList的出现替代了Vector.但是查询的速度很快.

|--Vector:底层数据结构是数组结构。jdk1.0版本。线程安全的。无论增删还是查询都非常慢。

|--LinkedList:底层是链表数据结构。线程不安全的,同时对元算的增删操作效率很高

可变长度的数组:

ArrayList内部封装了一个默认长度为10的数组;当超出长度时,集合内部会自动生成一个新的数组;将原数组中的元素复制到新数组中,在将新元素添加到新数组。

新数组的长度:

ArrayList 50%延长。

Vector 100%延长。

Vector中提供了一个独特的取出方式,就是枚举Enumeration;此接口Enumeration的功能与 Iterator 接口的功能是重复的

Enumeration的名称和方法的名称过程,书写很麻烦;所以被Iterator所取代,郁郁而终。

import java.util.*;

class VectorDemo{

public static void main(String[] args) {

Vector v = new Vector();

v.addElement("abc1");

v.addElement("abc2");

v.addElement("abc3");

v.addElement("abc4");

Enumeration en = v.elements();

while(en.hasMoreElements()){

System.out.println(en.nextElement());

}

Iterator it = v.iterator();

while(it.hasNext()){

System.out.println(it.next());

}

}

}

八:列表迭代器的应用:

在进行迭代过程中,如果出现了迭代器和容器同时对元素进行操作的情况很容易引发ConcurrentModificationException并发修改异常.

解决:要么使用集合的方法操作元素,要么使用迭代器的方法操作元素;不要同时使用。

但是 迭代器Iterator中只有三个操作,判断hasNext,获取next,删除remove。

想要其他的操作时,比如添加,这个迭代器就不可以使用了。这时对于List集合,有一个新的迭代方式, 就是ListIterator 列表迭代器。

ListIterator本身也是Iterator的子接口。并提供了更多的迭代过程中的操作在迭代过程中,如果需要增删改查元素的操作,需要列表迭代器。

但是注意:该迭代器,只能用于List集合。

import java.util.*;

class ListIteratorDemo{

public static void main(String[] args) {

List list = new ArrayList();

list.add("abc1");

list.add("abc2");

list.add("abc3");

list.add("abc4");

ListIterator lit = list.listIterator();

System.out.println(lit.hasPrevious());

while(lit.hasNext()){

String s = (String)lit.next();

if(s.equals("abc2"))

//lit.add("haha");

lit.set("qq");

}

System.out.println(list);

System.out.println(lit.previous());

Iterator it = list.iterator();

while(it.hasNext()){

String s =(String)it.next();

if(s.equals("abc2"))

list.add("haha");//ConcurrentModificationException

System.out.println("s="+s);

}

System.out.println(list);

}

}

九:List和Set的用法区别:

A.|--List:有序(存的顺序和取的顺序一致。),元素可以重复,元素都有索引。

|--ArrayList:

|--LinkedList:

|--Set:无序,不可以重复元素。Set接口的方法和Collection中的方法一致。

Set接口取出元素的方法只有迭代器。

|--HashSet:底层数据结构是哈希表。哈希表这种结构,其实就是对哈希值的存储。

而且每一个对象都有自己的哈希值。因为Object类中的有一个方法hashCode方法。

B.如何保证元素唯一性的呢?

通过判断元素的hashCode方法,和equals方法完成的;

当hashCode值相同是,会在判断一次euqals方法的返回只是是否为true。

如果hashCode值不相同,就确定元素的哈希表中的位置,就不用在判断equals了。

当哈希表中有一个桶结构。每一个桶都有一个哈希值,当哈希值相同,但是equals为false时,表示为不同元素。

原理:这些元素都存放一个桶里。

|--TreeSet:可以对Set集合中的元素进行排序:

数据结构是二叉树数据结构。这种结构,可以提高排序性能。

1.它又是如何保证元素唯一性的呢?

是根据比较方法的返回值确定的:只要返回的是0,就代表元素重复。

2.HashSet集合保证元素唯一性的原因:

HashSet集合保证元素唯一性,依赖的是元素的hashCode方法和euqals方法。

当元素的哈希值不同时,元素都有自己的独立位置,不需要在判断元素的equals方法;

3.当元素的哈希值相同时,这时元素在哈希表中位置相同,这时就需要在判断一次元素的内容是否相同;就需要调用元素的equals方法进行一次比较。如果equals返回是true,那么视为两个元素为重复元素,只储存一个。如果返回是false,那么这两个元素不是重复元素,会存储在同一个哈希值上。

4.为了建立自定义对象判断元素是否重复的依据:

需要覆盖hashCode方法,和equals方法:而且最好依据对象的特有条件来建立hashcode和euqals的实现。

ArrayList:判断包含,以及删除,都是依据元素的equals方法。

HashSet:判断包含,以及删除,都是依据元素的hashCode方法。当hashCode值相同时,在判断一次equals方法。

实用小技巧:

ArrayList: 数组

LinkedList:链表

HashSet:哈希表

TreeSet:二叉树

看到Array就要想到数组,就要想到角标,就要想到查询很快.

看到Link就要想到链表.就要想要增删很快.最好再想到 addFirst(offerFirst)

看到Hash就要想要哈希表,就要想到元素的hashCode方法,和equals方法。

看到Tree,就要想要二叉树,就要想要排序。就要想到两个接口 Comparable 和Comparator。

需要明确的是什么时候List,什么时候用Set?

保证元素唯一,就用Set集合;不需要就使用List集合;实在搞不清楚,就用ArrayList。

Treeset集合使用于给元素进行排序的;那么自定义元素本身不具备比较性,Treeset集合是无法对元素进行排序的;

所以,在自定义对象时,需要对象具备一个扩展功能,用于比较的,

而java已经提供了接口,可以让实现它的对象具备比较性;那么自定义类,要想被Treeset排序,就需要实现Comparable接口;以具备比较功能。

比较的时候,要注意,主要条件和次要条件;如果主要条件相同,一定要比较次要条件。

当Treeset集合中存储的元素不具备比较功能;或者具备的比较功能不是所需要的。

例如:Person对象中的自然排序是按照年龄排序。

但是现在需求是想安装姓名排序。该源代码这种方式想都不要想。有这种想法就是犯罪。

该如何解决这个问题?

既然元素具备的比较方式不满足应用;这时,可以让集合自身具备比较性。

需要集合一初始化就具备比较功能。因为要在添加元素前具备。

就需要在构造函数进行初始化。

只要将一个实现了Comparator接口的子类对象作为参数传递给TreeSet集合的构造函数即可。

这样该集合就具备了比较功能。

建议使用第二种排序方式。

应用:

TreeSet排序方式有两种。

1,让元素自身具备比较性。

其实是让元素实现Comparable接口,覆盖compareTo方法。

这称为元素的自然排序。

2,当元素自身不具备比较性,或者元素具备的比较性不是所需要的,

可以让集合自身具备比较性。

定义一个比较器:

其实就是定义一个类,实现Comparator接口。覆盖compare方法。

将Comparator接口的子类对象作为参数传递给TreeSet的构造函数。

当元素自身具备比较性,同时TreeSet集合也具备比较器,这时以比较器为主。

十:学习了这么多,来一个总体总结:

一般在描述一个对象时,如果该对象封装了具体的数据,会出现很多这样的对象比如:员工,学生对象等.

这时就需要进行容器的存储.那么描述该类对象时,一定要复写几个方法:

1,hashCode()

2,equals()

3,toString()

4,最好实现Comparable接口让该类具备自然排序功能。

建立对象自身判断是否相同的依据,同时让对象具备基本的比较性。

代码体现:

class TreeSetDemo3{

public static void main(String[] args) {

TreeSet ts = new TreeSet(newCompareByName());

ts.add(new Person("lisi1",21));

ts.add(new Person("lisi4",29));

ts.add(new Person("lisi2",67));

ts.add(new Person("lisi8",28));

ts.add(new Person("lisi0",20));

System.out.println(ts);

}

}

//自定义一个比较器。

classCompareByName implements Comparator{

public int compare(Object o1,Object o2){

Person p1 = (Person)o1;

Person p2 = (Person)o2;

int num =p1.getName().compareTo(p2.getName());

returnnum==0?p1.getAge()-p2.getAge():num;

}

}

class Personimplements Comparable{

private String name;

private int age;

Person(String name,int age){

this.name = name;

this.age = age;

}

//人的自然排序是按照年龄排序

public int compareTo(Object obj){

Person p = (Person)obj;

int num = newInteger(this.age).compareTo(new Integer(p.age));

returnnum==0?this.name.compareTo(p.name):num;

}

public String getName(){

return name;

}

public int getAge(){

return age;

}

public String toString(){

return name+"::"+age;

}

}

------- android培训java培训、期待与您交流! ----------  详细请查看:http://edu.csdn.net/heima/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐