黑马程序员-学习日记
黑马程序员_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 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/