黑马程序员博客-------集合Collection
集合
集合类由来:对象用于封装特有的数据,对象多了需要存储,如果对象的个数不确定,就使用集合容器进行存储。
集合的特点:(数组和集合的区别)
- 用于存储对象的容器
- 集合的长度是可变的。
- 集合中不可以存储基本数据类型值。
集合容器因为内部的数据结构不同,有多种具体的容器,不断向上抽取就行成了集合框架。
框架的顶层是Collection接口:
Collection的常见方法:
- 添加
boolean add(Object obj);
boolean addAll(Collection coll);
- 删除。
boolean remove(Object obj);删除一个元素
boolean remove All(Collection coll);删除指定集合元素
clear();删除全部元素
- 判断:
boolean contains(Object obj);
boolean containsAll(Collection coll);
boolean isEmpty()
- 获取:
int size()
Iterator iterator();迭代器: 该对象必须依赖于具体容器,因为每一个容器的数据结构都不同。所以该迭代器对象是在内部实现的,对于使用容器者而言,具体的实现不重要,只要通过容器获取到该实现的迭代器对象即可,也就是iterator方法。Iterator接口就是对所有的Collection容器进行元素取出的公共接口。
1 1.// Iterator it=coll1.iterator(); 2 3 // while(it.hasNext()) 4 5 // { 6 7 // System.out.println(it.next()); 8 9 // } 10 11 2. for (Iterator iterator = coll2.iterator(); iterator.hasNext();) { 12 13 System.out.println(iterator.next()); 14 15 16 17 }
迭代器的两种跌代方式,第一种weile循环后迭代器对象还驻留在内存中,后面还可以使用,第二种for循环后迭代器对象立即释放,第二种更省内存,如果在后面需要再次使用迭代器对象,建议使用第一种,否则建议使用第二种。
- 其他:
boolean retainAll(Collection coll)取交集,保留和指定的集合相同的元素,而删除不同的元素,和removeAll相反
Object [] toArray();将集合转成数组。
Collection
--List
--set
List和set的区别:
List:有序(存入和取出的顺序一致),元素都有索引(下标),元素可以重复
Set:元素不能重复,无序。
List特有的常见方法:这些方法都可以操作下标。
- 添加:
void add(index,element);// list.add("abc1");
void add(index,Collection);//
- 删除
Object remove(index);// list.remove(1);
- 修改:
Object set(index);返回的是被替换的元素(替换之前对应的角标的元素) list.set(0, "abc10")
- 获取:同用获取元素的方式,使用迭代器(list.iterator();)
如果在迭代的过程中使用了集合对象操作了元素,会发生异常,应该使用ListIterator列表迭代器,它可以实现在迭代的过程中对元素的增删改查,但只有list集合才具备这个功能。
例子:
1 ListIterator iterator=list.listIterator(); 2 3 while(iterator.hasNext()) 4 5 { 6 7 Object obj=iterator.next(); 8 9 if(obj.equals("abc2")) 10 11 iterator.add("abc10"); 12 13 else 14 15 System.out.println(obj); 16 17 } 18 19 Object get(index);//list.get(1);这是list专用的获取元素的方式。 20 21 int indexOf(Object) 22 23 int lastIndexOf(Object); 24 25 List subList(fromindex,toindex)//返回列表中的指定范围,包含头,不包含尾。
List
Vector:内部是数组数据结构。数组长度是可变的,超出后延长100%,是同步的(线程安全),效率低,增删查询都很慢
ArrayList:内部是数组数据结构,数组长度是可变的,超出后延长50%,是不同步的,效率高,替代了Vector ,查询的速度很快
1 ArrayList a1=new ArrayList(); 2 3 a1.add(new Person("张三", 21));//存 4 5 a1.add(new Person("李四", 22)); 6 7 a1.add(new Person("王五", 23)); 8 9 a1.add(new Person("赵六", 24)); 10 11 a1.add(new Person("马七", 25)); 12 13 Iterator it=a1.iterator();//开始取 14 15 while(it.hasNext()) 16 17 { 18 19 //存自定义对象的时候取的时候必须要强制转换,在while中最好只写一次next()方法 20 21 Person p=(Person)it.next(); 22 23 System.out.println("姓名:"+p.getName()+" 年龄:"+p.getAge()); 24 25 } 26 27 }
LinkedList:内部是链表数据结构,是不同步的。增删元素的速度很快
void addFirst(E e) 将指定元素插入此列表的开头。
void addLast(E e) 将指定元素添加到此列表的结尾。这个方法等效于add(e)
E getFirst()返回此列表的第一个元素,获取但不移除,如果链表为空则抛出NoSuchElementException,
E getLast()返回此列表的最后一个元素
E removeFirst()移除并返回此列表的第一个元素。
E removeLast()移除并返回此列表的最后一个元素。
jdk1.6以后
peekFirst();获取但不移除,如果链表为空则返回null
E peekLast()获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。
E pollLast()获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。
Set:元素不能重复,无序。
Set接口中的方法和Collection是一样的。
|----HashSet:内部数据结构是哈希表,内容是不同步的
哈希表确定元素是否相同:1.判断的是两个元素的哈希值是否相同(判断的是对象的hashCode方法)。如果相同,再判断两个对象的内容是否相同(用的是equals方法),如果哈希值不同是不需要判断equals
1 HashSet hs=new HashSet(); 2 3 hs.add("haha"); 4 5 hs.add("hehe"); 6 7 hs.add("xixi"); 8 9 hs.add("dada"); 10 11 Iterator it=hs.iterator(); 12 13 while(it.hasNext()) 14 15 { //输出是无序的 16 17 System.out.println(it.next()); 18 19 }
HashSet有一个子类LinkedHashSet: 具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现,是不重复,有序的链表,方法和HashSet一样
|----TreeSet:可以对Set集合中的元素进行指定顺序的排序。是不同步的
判断元素唯一性的方式:就是根据比较方法的返回结果是否是0,是0是相同的元素
TreeSet对元素进行排序的方式1:让元素自身具备比较功能,元素就需要实现Comparable接口。覆盖compareTo方法
1 class Person implements Comparable{ 2 3 .. … .. ... 4 5 public int compareTo(Object o) { 6 7 Person p=(Person)o; 8 9 int temo=this.age-p.age;//比较对象的age的差, 10 11 return temo==0?this.name.compareTo(p.name):temo;//如果比较的等于0,再比较name 12 13 /* if(p.age>this.age) 比较对象的age 14 15 return 1; 16 17 if(p.age<this.age) 18 19 return -1; 20 21 if(p.age==this.age) 22 23 return this.name.compareTo(p.name);如过age相同就比较name 24 25 return 0;*/ 26 27 }
如果不按照对象中具备的自然顺序进行排序(对象中有可能不具备自然顺序)
可以让TrreSet集合自身具备比较功能,定义一个类实现Comparator接口,覆盖compare方法,将该类对象作为参数传递给TReeSet集合的构造函数
package com;
import java.util.Comparator;
import com.bean.Person;
/**
* 创建一个根据Person类的name进行比较的比较器
*/
1 public class ComparableByname implements Comparator { 2 3 public int compare(Object o1,Object o2) { 4 5 Person p1=(Person)o1; 6 7 Person p2=(Person)o2; 8 9 int item=p1.getName().compareTo(p2.getName()); 10 11 return item==0? p1.getAge()-p2.getAge():item; 12 13 } 14 15 } 16 17 .. .. .. .... 18 19 public static void main(String[] args) { 20 21 TreeSet ts=new TreeSet(new ComparableByname());
需要唯一性吗?
需要:Set
需要制定顺序:TreeSet
不需要顺序:HashSet
唯一和存的顺序一致:LinkedHashSet
不需要:List
需要频繁的增加和删除:LinkedList
不需要频繁的增删:ArrayList
总结:后缀名就是该集合所属的体系。
前缀名就是该集合的数据结构。
看到array:就要想到数组,就要想到查询快,有角标.
看到link:就要想到链表,就要想到增删快,就要想要 add get remove+frist last的方法
看到hash:就要想到哈希表,就要想到唯一性,就要想到元素需要覆盖hashcode方法和equals方法。
看到tree:就要想到二叉树,就要想要排序,就要想到两个接口Comparable,Comparator 。
而且通常这些常用的集合容器都是不同步的。