一、集合类的由来
对象用于封装特有数据,对象多了需要存储;如果对象的个数不确定,就使用集合容器进行存储。
集合特点:1. 用于存储对象的容器。
2. 集合的长度是可变的。
3. 集合中不可以存储基本数据类型值。
集合容器因为内部的数据结构不同,有多种具体容器。不断的向上抽取,就形成了集合框架。
经典问题:数组和集合类同是容器,有何不同?
数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。
数组中可以存储基本数据类型,集合只能存储对象。
集合框架的构成及分类如图所示:
。
二、Collection接口
框架的顶层Collection接口:
Collection的常见方法:
1、添加:
boolean add(Object obj);
boolean addAll(Collection coll);
2、删除:
boolean remove(Object obj);
boolean removeAll(Collection coll);
void clear();
3、判断:
boolean contains(Object obj);
boolean containsAll(Collection coll);
boolean isEmpty();判断集合中是否有元素。
4、获取:
int size();
Iterator iterator();
取出元素的方式:迭代器。
该对象必须依赖于具体容器,因为每一个容器的数据结构都不同,所以该迭代器对象是在容器中进行内部实现的,也就是iterator方法在每个容器中的实现方式是不同的。
对于使用容器者而言,具体的实现不重要,只要通过容器获取到该实现的迭代器的对象即可,也就是iterator方法。
Iterator接口就是对所有的Collection容器进行元素取出的公共接口。
5、其他:
boolean retainAll(Collection coll);取交集
Object toArray();将集合转成数组
示例:
- import java.util.*;
- public class CollectionDemo {
- public static void main(String[] args){
- Collection coll = new ArrayList();
- show(coll);
- System.out.println( "---------------------------------" );
- Collection c1 = new ArrayList();
- Collection c2 = new ArrayList();
- show(c1,c2);
- }
- public static void show(Collection coll){
- //1、添加元素,add
- coll.add( "abc1");
- coll.add( "abc2");
- coll.add( "abc3");
- System.out.println( "coll:" + coll);
- //2、删除元素,remove
- coll.remove( "abc2");//会改变集合的长度
- System.out.println( "coll:" + coll);
- //清空集合
- //coll.clear();
- System.out.println(coll.contains( "abc1"));
- }
- public static void show(Collection c1,Collection c2){
- //给c1添加元素
- c1.add( "abc1");
- c1.add( "abc2");
- c1.add( "abc3");
- c1.add( "abc4");
- //给c2添加元素
- c2.add( "abc2");
- c2.add( "abc6");
- c2.add( "abc7");
- System.out.println( "c1:" + c1);
- System.out.println( "c2:" + c2);
- //演示addAll
- //将c2中的元素添加到c1中
- c1.addAll(c2);
- //演示removeAll
- //从c1集合中删除与c2集合相同的元素
- boolean b = c1.removeAll(c2);
- System.out.println( "removeAll:" + b);
- //演示containsAll
- boolean b1 = c1.containsAll(c2);
- System.out.println( "containsAll:" + b1);
- //演示retainAll
- //取交集,保留和指定的集合相同的元素
- boolean b2 = c1.retainAll(c2);
- System.out.println( "c1、c2交集:" + c1);
- }
- }
示例2:
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Iterator;
- public class IteratorDemo{
- public static void main(String[] args){
- Collection coll = new ArrayList();
- coll.add( "abc1");
- coll.add( "abc2");
- coll.add( "abc3");
- coll.add( "abc4");
- System.out.println(coll);
- /*使用了Collection中的iterator()方法。调用集合中的迭代器方法,是为了获取集合中
- 的迭代器对象。*/
- Iterator it1 = coll.iterator();
- while(it1.hasNext()){
- System.out.println(it1.next());
- }
- //for循环结束,Iterator变量内存释放,更高效
- for(Iterator it2 = coll.iterator();it2.hasNext();){
- System.out.println(it2.next());
- }
- }
- }
三、List、Set
Collection
|--List:有序(存入和取出的顺序一致),元素都有索引(角标),允许重复元素。
|--Set:元素不能重复,无序。
List:特有的常见方法。
有一个共性特点就是都可以操作角标。
1、添加
void add(index,element);
void addAll(index,collection);
2、删除
Object remove(index);
3、修改
Object set(index,element);
4、获取:
Object get(index);
int indexOf(object);
int lastIndexOf(object);
List subList(from,to);
List集合可以完成对元素的增删改查。
示例:
- import java.util.ArrayList;
- import java.util.List;
- public class ListDemo{
- public static void main(String[] args){
- List list = new ArrayList();
- show(list);
- }
- public static void show(List list){
- //添加元素
- list.add( "abc1" );
- list.add( "abc2" );
- list.add( "abc3" );
- System.out.println(list);
- //插入元素
- list.add(1, "abc2" );
- //删除元素
- System.out.println( "remove:" + list.remove(2));
- //修改元素
- System.out.println( "set:" + list.set(1,"abc8" ));
- //获取元素:
- System.out.println( "get:" + list.get(0));
- //获取子列表
- System.out.println( "sublist:" + list.subList(1,2));
- System.out.println(list);
- }
- }
示例2:
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- import java.util.ListIterator;
- public class ListDemo{
- public static void main(String[] args){
- List list = new ArrayList();
- show(list);
- }
- public static void show(List list){
- list.add( "abc1");
- list.add( "abc2");
- list.add( "abc3");
- list.add( "abc4");
- Iterator it = list.iterator();
- while(it.hasNext()){
- System.out.println( "next:" + it.next());
- }
- //list特有的取出元素的方式之一
- for(int x = 0; x < list.size(); x++){
- System.out.println( "get:" + list.get(x));
- }
- }
- }
示例3:
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- public 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);
- Iterator it = list.iterator();
- while(it.hasNext()){
- Object obj = it.next();
- if(obj.equals("abc2" )){
- list.add( "abc9");
- } else{
- System.out.println( "next:" + obj);
- }
- System.out.println(list);
- }
- }
- }
在迭代器过程中,不要使用集合操作元素,容易出现异常:java.util.ConcurrentModificationException。
可以使用Iterator接口的子接口ListIterator来完成在迭代中对元素进行更多的操作。
- import java.util.ArrayList;
- import java.util.List;
- import java.util.ListIterator;
- public 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);
- ListIterator it = list.listIterator(); //获取列表迭代器对象
- //它可以实现在迭代过程中完成对元素的增删改查。
- //注意:只有list集合具备该迭代功能。
- while(it.hasNext()){
- Object obj = it.next();
- if(obj.equals("abc3" )){
- it.add( "abc9");
- }
- }
- System.out.println( "hasNext:" + it.hasNext());
- System.out.println( "hasPrevious:" + it.hasPrevious());
- while(it.hasPrevious()){
- System.out.println( "previous:" + it.previous());
- }
- System.out.println( "list:" + list);
- }
- }
程序运行结果如图:。
四、Vector、ArrayList、LinkedList
List:
|--Vector:内部是数组数据结构,是同步的。增删,查询都很慢。
|--ArrayList:内部是数组数据结构,是不同步的,替代了Vector。替代了Vector,查询的速度快。
|--LinkedList:内部是链表数据结构,是不同步的。增删元素的速度很快。
LinkedList方法:
addFirst();
addLast();
jdk1.6版本后新方法:
offerFirst();与addFirst方法没有区别。
offerLast();与addLast方法没有区别。
---------------------------------------------------------
getFirst();//获取但不移除,如果链表为空,抛出NoSuchElementException。
getLast();
jdk1.6版本后新方法:
peekFirst();//获取但不移除,如果链表为空,返回null。
peekLast();
--------------------------------------------------------
removeFirst();//获取并移除,如果链表为空,抛出NoSuchElementException。
removeLast();
jdk1.6版本后新方法:
pollFirst();//获取并移除,如果链表为空,返回null;
pollLast();
示例:
- import java.util.Iterator;
- import java.util.LinkedList;
- public class LinkedListDemo{
- public static void main(String[] args){
- LinkedList link = new LinkedList();
- link.addFirst( "abc1");
- link.addFirst( "abc2");
- link.addFirst( "abc3");
- link.addFirst( "abc4");
- Iterator it = link.iterator();
- while(it.hasNext()){
- System.out.println( "next:" + it.next());
- }
- System.out.println(link);
- System.out.println("getFirst:" + link.getFirst()); //获取第一个,但是不删除。
- System.out.println("getLast:" + link.getLast());
- System.out.println("removeFirst:" + link.removeFirst()); //获取第一个,但是删除
- System.out.println("removeLast:" + link.removeLast());
- //删除所有元素的方法
- while(!link.isEmpty()){
- System.out.println(link.removeFirst());
- }
- }
- }
五、Set
Set:元素不可以重复,是无序。
Set接口中的方法和Collection一致。
|--HashSet:内部数据结构是哈希表,是不同步的。
|--TreeSet:可以对Set集合中的元素进行排序,是不同步的。
示例:
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.Set;
- public class HashSetDemo{
- public static void main(String[] args){
- Set hs = new HashSet();
- hs.add( "hashhaha");
- hs.add( "hashheihei");
- hs.add( "hashhehe");
- hs.add( "hashxixi");
- Iterator it = hs.iterator();
- while(it.hasNext()){
- System.out.println(it.next());
- }
- }
- }
哈希表确定元素是否相同
1. 判断的是两个元素的哈希值是否相同。如果相同,再判断两个对象的内容是否相同。
2. 判断哈希值相同,其实判断的是对象的HashCode方法。判断内容相同,用的是equals方法。
PS:
如果哈希值不同,不需要判断equals。往HashSet集合中存储Person对象。如果姓名和年龄相同,视为同一个人,视为相同元素。
- import java.util.HashSet;
- import java.util.List;
- import java.util.Iterator;
- public class HashSetTest{
- public static void main(String[] args){
- HashSet hs = new HashSet();
- hs.add( new Person("lisi4" ,24));
- hs.add( new Person("lisi7" ,27));
- hs.add( new Person("lisi1" ,21));
- hs.add( new Person("lisi9" ,29));
- hs.add( new Person("lisi7" ,27));
- 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;
- public Person(){
- }
- public Person(String name,int age){
- this.name = name;
- this.age = age;
- }
- public void setName(String name){
- this.name = name;
- }
- public String getName(){
- return this .name;
- }
- public void setAge(int age){
- this.age = age;
- }
- public int getAge(){
- return this .age;
- }
- public int hashCode(){
- return name.hashCode() + age * 39;
- }
- public boolean equals(Object obj){
- if(this == obj)
- return true ;//同一个对象放两次,直接返回true
- if(!(obj instanceof Person))
- throw new ClassCastException("类型错误");
- Person p = (Person)obj;
- return this .name.equals(p.name) && this.age == p.age;
- }
- }
定义功能去除ArrayList中的重复元素
示例:
- import java.util.ArrayList;
- import java.util.List;
- import java.util.ListIterator;
- public class ArrayListTest {
- public static void main(String[] args) {
- List<String> list = new ArrayList<String>();
- list.add("a");
- list.add("a");
- list.add("b");
- list.add("b");
- list.add("c");
- list.add("c");
- List<String> li = getSingleElement(list);
- System.out.println(li);
- }
- public static List<String> getSingleElement(List<String> list) {
- ArrayList<String> temp = new ArrayList<String>();
- ListIterator<String> it = list.listIterator();
- while(it.hasNext()){
- String str = it.next();
- if(!temp.contains(str))
- temp.add(str);
- }
- return temp;
- }
- }
TreeSet对元素进行排序的方式一: 让元素自身具备比较功能,元素就需要实现Comparable接口,覆盖compareTo方法。
如果不要按照对象中具备的自然顺序进行排序。如果对象中不具备自然顺序。怎么办?
可以使用TreeSet集合第二种排序方式:让集合自身具备比较功能,定义一个类实现Comparator接口,覆盖compare方法。将该类对象作为参数传递给TreeSet集合的构造函数。
PS:
如果自定义类实现了Comparable接口,并且TreeSet的构造函数中也传入了比较器,那么将以比较器的比较规则为准。
TreeSet集合的底层是二叉树进行排序的。
示例:对字符串进行长度排序
- import java.util.Comparator;
- import java.util.Iterator;
- import java.util.TreeSet;
- public class TreeSetTest{
- public static void main(String[] args){
- TreeSet ts = new TreeSet(new ComparatorByLen());
- ts.add( "aaaa");
- ts.add( "zz");
- ts.add( "nbag");
- ts.add( "cba");
- ts.add( "abc");
- Iterator it = ts.iterator();
- while(it.hasNext()){
- System.out.println(it.next());
- }
- }
- }
- class ComparatorByLen implements Comparator{
- public int compare(Object o1,Object o2){
- String s1 = (String)o1;
- String s2 = (String)o2;
- int temp = s1.length() - s2.length();
- return temp == 0?s1.compareTo(s2):temp;
- }
- }