Java集合类主要分为以下三类: 第一类:Array、Arrays 第二类:Collection :List、Set 第三类:Map :HashMap、HashTable 一、Array , Arrays…
Java: set和list集合类的使用方法
集合概述
由于Set集合和List集合都继承于Collection,都用于管理多个对象,所以统称为集合类。如下图所示:

数组与集合类都可以用于管理多个对象,有何不同?
数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象。
集合类的特点?
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
Java集合框架实际上是java对各种数据结构的实现。比如,线性表,链表,队列,堆,栈,二叉树等,不像C语言,需要全部自己实现。
共性方法
由于大部分集合类都继承了Collection接口,所以Collection接口的方法就是集合类的共性方法,演示代码如下:
首先演示操作一个元素的方法,主要用于添加、删除和判断。一共6个:
public static void demo1(){ Collection col1=new ArrayList(); col1.add("java01"); col1.add("java02"); col1.add("java03"); col1.add("java04"); System.out.println(col1); col1.remove("java01"); System.out.println(col1); col1.clear(); System.out.println(col1.size()); System.out.println(col1.isEmpty()); System.out.println(col1.contains("java01")); col1.add("java01"); System.out.println(col1.contains("java01")); }
运行结果:
[java01, java02, java03, java04] [java02, java03, java04] 0 true false true
由以上代码可知:
1.add方法的参数类型为Object
2.集合中存储的都是对象的引用
然后演示操作一组元素(集合)的方法,一共4个:
public static void demo2(){ Collection col1=new ArrayList(); col1.add("java01"); col1.add("java02"); Collection col2=new ArrayList(); col2.add("java01"); col2.add("java03"); String demoMethod="containsAll"; switch (demoMethod) { case "addAll": //求并集,重复不合并 col1.addAll(col2);//[java01, java02, java01, java03] System.out.println(col1); break; case "removeAll": col1.removeAll(col2);//[java02]求差集 System.out.println(col1); break; case "retainAll": col1.retainAll(col2);//[java01]求交集 System.out.println(col1); break; case "containsAll": col1.add("java03"); System.out.println(col1.containsAll(col2));//true default: break; } }
学习本节后的结合框架如图,红色为本节学习:

本节学了1个接口,10个方法的用法
迭代器
迭代器是逐个取出集合元素的方式,迭代器接口在各个集合类中实现都不一样。每个集合类的iterator()方法返回的迭代器对象也不一样,是每个集合内部定义的类。
使用迭代器获取元素的代码如下:
public static void demo3(){ Collection col1=new ArrayList(); for (int i = 0; i < 10000; i++) { col1.add("测试数据"+i); } long startTime=System.currentTimeMillis(); //用迭代器取出元素方式1,传统方式 // Iterator it=col1.iterator(); // while(it.hasNext()){ // System.out.println(it.next()); // } //用迭代器取出元素方式2,将迭代器在for循环的第一个;前定义,可以提高性能 for (Iterator it=col1.iterator();it.hasNext();) { System.out.println(it.next()); } System.out.println(System.currentTimeMillis()-startTime); }
学习本节后,集合框架体系图为:

本节学习了1个接口,3个方法,本章到这学习了2个接口,13个方法
List集合共性方法
List接口和Set接口对比:
List:元素是有序的,元素可以重复。该集合体系有索引
Set:元素是无序的,元素不可以重复。
List集合特有方法。凡是可以操作角标的方法都是该体系特有的方法。元素索引从0开始。
增
add(index,element);加到index指向的元素前边
addAll(index,Collection);
删
remove(index);
改
set(index,element);
查
get(index);
indexOf();
subList(from,to);
listIterator();
public static void demo1(){ List list1=new ArrayList(); list1.add("java01"); list1.add("java02"); list1.add("java03"); List list2=new ArrayList(); list2.add("java04"); list2.add("java05"); String method="indexOf(element)"; switch (method) { case "add(index,element)": list1.add(0,"java04"); System.out.println(list1); list1.add(1,"java05"); System.out.println(list1); break; case "addAll(index,Collection)": list1.addAll(2,list2); System.out.println(list1); break; case "remove(index)": list1.remove(1); System.out.println(list1); list1.remove(1); System.out.println(list1); break; case "set(index,element)": list1.set(1, "java11"); System.out.println(list1); break; case "get(index)": //获取一个元素 System.out.println(list1.get(0)); //获取所有元素 for (int i = 0,max=list1.size(); i < max; i++) { System.out.println(list1.get(i)); } break; case "subList(from,to)": List list3=list1.subList(1, 3); System.out.println(list3); break; case "indexOf(element)": int index=list1.indexOf("java01"); System.out.println(index); break; default: break; } }
学习本节后集合框架体系图为:

本节学习了1个接口,7个方法,本章到这学习了3个接口,20个方法
ListIterator
ListIterator是List集合特有的迭代器。ListIterator是Iterator的子接口。Iterator的局限性:Iterator迭代时不能通过集合对象的方法操作集合中的元素,否则会发生ConcurrentModificationException异常。所以在迭代时,只能用迭代器的方法操作元素,可是Iterator中只有判断,取出和删除的操作。如果想要进行其他操作如添加,修改等,就需要使用其他子接口,既ListIterator。该接口只能通过List集合的listIterator()方法获取。
下面的代码演示Iterator的局限性和remove方法
public static void demo2(){ List list1=new ArrayList(); list1.add("java01"); list1.add("java02"); list1.add("java03"); Iterator it=list1.iterator(); while(it.hasNext()){ Object obj= it.next(); if (obj.equals("java02")) { / list1.add("java04");//不能添加元素,会报异常 it.remove();//Iterator的方法,从集合中删除java02的引用 System.out.println(obj);//删除的是引用而不是对象,所以能取到 } } System.out.println(list1); }
下面的代码演示ListIterator的用法
public static void demo3(){ List list1=new ArrayList(); list1.add("java01"); list1.add("java02"); list1.add("java03"); System.out.println(list1); ListIterator it=list1.listIterator(); while(it.hasNext()){ Object obj= it.next(); if (obj.equals("java02")) { //可以用list迭代器自己的add和set方法, //但不能同时使用,否则报异常 // it.add("java05"); it.set("java04"); } } System.out.println(list1); }
下面的代码演示ListIterator正向遍历和逆向遍历
public static void demo4(){ List list1=new ArrayList(); list1.add("java01"); list1.add("java02"); list1.add("java03"); ListIterator it=list1.listIterator(); while(it.hasNext()){ System.out.println(it.nextIndex()); System.out.println(it.next()); } while(it.hasPrevious()){ System.out.println(it.previousIndex()); System.out.println(it.previous()); } }
注意,直接逆向遍历是没有结果的,it.previousIndex()初始会返回-1。需要先用正向遍历把指针调到最后一个位置,才能开始逆向遍历,所以逆向遍历很少用,一般用previous()方法配合next()方法使用。
学习本节后集合框架体系图为:

本节学习了1个接口,7个方法,本章到这学习了4个接口,27个方法
List集合具体对象特点
ArrayList:底层使用数组。特点:查询速度很快,增删稍慢,线程不同步。
LinkedList:底层使用链表。特点:增删很快,查询稍慢。
Vector:底层使用数组。线程同步。历史较长。现被ArrayList替代。
Vector中有一系列方法带element,这是它特有的方法,这些方法和Collection集合中的方法重复,且元素名过长,所以被取代,还有一个elements()方法返回Enumeration对象,Enumeration接口和Iterator接口功能雷同,但是方法名过长,所以被Iterator取代。
Vector中的部分方法演示如下:
public static void demo5(){ Vector v=new Vector(); v.add("java01"); v.add("java02"); v.add("java03"); v.add("java04"); Enumeration en=v.elements(); while (en.hasMoreElements()) { System.out.println(en.nextElement()); } }
LinkedList
LInkedList特有方法:
添加元素
addFirst()
addLast()
获取元素,但删除元素。如果集合中没有元素,会出现NoSuchElementException
getFirst()
getLast()
获取元素,但是元素被删除。如果集合中没有元素,会出现NoSuchElementException
removeFirst()
removeLast()
JDK1.6后出现了替代方法
添加元素
offerFirst()
offerLast()
获取元素,但删除元素。如果集合中没有元素,会返回null
peekFirst()
peekLast()
获取元素,但是元素被删除。如果集合中没有元素,会返回null
pollFirst()
pollLast()
演示代码如下:
public static void demo1(){ LinkedList link=new LinkedList(); link.addFirst("java01"); link.addFirst("java02"); link.addFirst("java03"); link.addFirst("java04"); System.out.println(link); String method="pollLast"; switch (method) { case "addLast": link.addLast("java05"); link.addLast("java06"); System.out.println(link); break; case "getFirst": System.out.println(link.getFirst()); System.out.println(link); break; case "getLast": System.out.println(link.getLast()); System.out.println(link); break; case "removeFirst": System.out.println(link.removeFirst()); System.out.println(link); break; case "removeLast": System.out.println(link.removeLast()); System.out.println(link); break; case "offerfirst": link.offerFirst("java05"); link.offerFirst("java06"); System.out.println(link); break; case "offerLast": link.offerLast("java05"); link.offerLast("java06"); System.out.println(link); break; case "peekFirst": System.out.println(link.peekFirst()); System.out.println(link); break; case "peekLast": System.out.println(link.peekLast()); System.out.println(link); break; case "pollFirst": System.out.println(link.pollFirst()); System.out.println(link); break; case "pollLast": System.out.println(link.pollLast()); System.out.println(link); break; default: break; } }
下面用LinkedList模拟一个堆栈或队列
堆栈:先进后出 First In Last Out FILO,如同一个杯子
队列:先进先出 First In First Out FIFO
import java.util.LinkedList; class Queue{ private LinkedList link; public Queue(){ link=new LinkedList(); } public void push(Object obj){ link.offerFirst(obj); } public Object pop(){ return link.pollLast(); } public boolean isNull(){ return link.isEmpty(); } } class Stack{ private LinkedList link; public Stack(){ link=new LinkedList(); } public void push(Object obj){ link.offerFirst(obj); } public Object pop(){ return link.pollFirst(); } public boolean isNull(){ return link.isEmpty(); } } public class LinkedListDemo { public static void main(String[] args) { Queue queue=new Queue(); queue.push("java01"); queue.push("java02"); queue.push("java03"); while (!queue.isNull()) { System.out.println(queue.pop()); } Stack stack=new Stack(); stack.push("java01"); stack.push("java02"); stack.push("java03"); while (!stack.isNull()) { System.out.println(stack.pop()); } } }
学习本节后集合框架体系图为:

本节学习了1个类,12个方法,本章到这学习了1个类,4个接口,39个方法.
ArrayList
一般情况下创建集合默认用ArrayList,如果增删很多用LinkedList。编写代码去除ArrayList中的重复元素
import java.util.ArrayList; import java.util.Iterator; public class ArrayListDemo { public static void main(String[] args) { ArrayList list=new ArrayList(); list.add("java01"); list.add("java02"); list.add("java01"); list.add("java03"); list=singleElement(list); System.out.println(list); } public static ArrayList singleElement(ArrayList list){ Iterator it=list.iterator(); ArrayList temp=new ArrayList(); while (it.hasNext()) { Object object = (Object) it.next(); if (!temp.contains(object)) { temp.add(object); } } return temp; } }
将自定义对象作为元素存到ArrayList集合中,并去除重复元素。
比如:存人独享。同姓名同年龄,视为同一个人,为重复元素。
import java.util.ArrayList; import java.util.Iterator; class Person{ private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } @Override public boolean equals(Object obj) { if (obj instanceof Person) { Person p=(Person)obj; return p.getName()==this.getName()&&p.getAge()==this.getAge(); } return super.equals(obj); } } public class ArrayListDemo { public static void main(String[] args) { ArrayList list=new ArrayList(); list.add(new Person("lisi01", 23)); list.add(new Person("lisi02", 21)); list.add(new Person("lisi03", 19)); list.add(new Person("lisi02", 21)); list=singleElement(list); list.remove(new Person("lisi01", 23)); Iterator it=list.iterator(); while (it.hasNext()) { Person p = (Person) it.next(); System.out.println(p.getName()+"的年龄为"+p.getAge()); } } public static ArrayList singleElement(ArrayList list){ Iterator it=list.iterator(); ArrayList temp=new ArrayList(); while (it.hasNext()) { Object object = (Object) it.next(); if (!temp.contains(object)) { temp.add(object); } } return temp; } }
上面的代码中实际上Person对象的equals方法是Collection对象的contains方法调用的。
本节学习了1个类(ArrayList),1个方法(equals()),截止到目前已经学习了3个类,4个接口,40个方法
HashSet
Set:元素是无序的(存入和取出的顺序不一致),元素不允许重复
|–HashSet:底层数据结构是哈希表。通过Object上的hashCode方法来判断元素是否重复,如果hashCode一样,则进一步通过equals方法判断,如果连equals都一样,则确认是重复元素
Set接口和Collection接口方法一样,所以用法没有区别。
hashCode()方法是Object类上的方法
下面的代码演示HashSet集合的元素无序性和唯一性
import java.util.HashSet; import java.util.Iterator; public class HashSetDemo { public static void main(String[] args) { HashSet set=new HashSet(); System.out.println(set.add("java01")); System.out.println(set.add("java01")); set.add("java02"); set.add("java03"); set.add("java04"); Iterator it=set.iterator(); while (it.hasNext()) { System.out.println(it.next()); } } }
在HashSet中存储自定义对象,例如Person对象,并重写hashCode和equals方法:
import java.util.HashSet; import java.util.Iterator; class Person{ private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } @Override public boolean equals(Object obj) { System.out.println(name+".equals"); if (obj instanceof Person) { Person p=(Person)obj; return p.getName()==this.getName()&&p.getAge()==this.getAge(); } return super.equals(obj); } @Override public int hashCode() { System.out.println(name+".hashCode"); return name.hashCode()+age*39; } } public class HashSetDemo { public static void main(String[] args) { HashSet set=new HashSet(); set.add(new Person("lisi01", 11)); set.add(new Person("lisi02", 21)); set.add(new Person("lisi02", 21)); set.add(new Person("lisi02", 26)); set.add(new Person("lisi03", 19)); Iterator it=set.iterator(); while (it.hasNext()) { Person p=(Person)it.next(); System.out.println(p.getName()+"的年龄是"+p.getAge()); } } }
下面演示HashCode的判断元素和删除元素方法
public static void main(String[] args) { HashSet set=new HashSet(); set.add(new Person("a1", 12)); set.add(new Person("a2", 34)); set.add(new Person("a3", 56)); System.out.println(set.contains(new Person("a2", 34))); System.out.println(set.remove(new Person("a2", 34))); Iterator it=set.iterator(); while (it.hasNext()) { Person p=(Person)it.next(); System.out.println(p.getName()+"的年龄是"+p.getAge()); } }
上面的代码和运行结果说明,HashSet的contains方法和remove方法也是靠hashCode()方法判断元素是否相同,hashCode相同再判断equals()方法。
本节学习了1个类(HashSet)、1个方法(hashCode())。本章到目前为止共学习了4个类、4个接口、41个方法
TreeSet
Set:无序,不可以重复元素。
|– HashSet:底层数据结构是哈希表。线程非同步的。
|– TresSet:可以对集合中的元素排序。底层数据结构是二叉树,通过元素的compareTo方法是否返回0保证元素唯一性。
TreeSet排序第一种方式:让元素自身具备比较性。
元素需要实现Comparable接口,覆盖compareTo方法。
这种方式称为元素的自然顺序或默认顺序。
TreeSet排序第二种方式:让容器具备比较性。
创建TreeSet时传入实现Comparator接口的类,覆盖compare方法。
这种方式比较常用,且此方式比第一种方式优先级高。
下面的代码,演示一下TreeSet的顺序问题:
TreeSet ts=new TreeSet(); ts.add("Dac"); ts.add("aac"); ts.add("bac"); ts.add("bbc"); Iterator it=ts.iterator(); while(it.hasNext()){ System.out.println(it.next()); }
运行结果:
Dac aac bac bbc
下面的代码演示TreeSet存储对象,并排序:
import java.util.Iterator; import java.util.TreeSet; class Student implements Comparable{ String name; int age; public Student(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } @Override public int compareTo(Object o) { if (!(o instanceof Student)) { throw new RuntimeException(); } Student s=(Student)o; if (this.age>s.getAge()) { return 1; }else if (this.age==s.getAge()) { return this.name.compareTo(s.name); } return -1; } } public class TreeSetDemo { public static void main(String[] args) { demo2(); } public static void demo2(){ TreeSet ts=new TreeSet(); ts.add(new Student("lisi01", 56)); ts.add(new Student("lisi02", 34)); ts.add(new Student("lisi03", 34)); ts.add(new Student("lisi04", 12)); Iterator it=ts.iterator(); while(it.hasNext()){ Student s=(Student)it.next(); System.out.println(s.getName()+"的年龄是:"+s.getAge()); } } }
注意:存入TreeSet集合中的元素类必须实现Comparable接口,并覆盖compareTo方法。方法抛出异常。compareTo方法的作用是确定对象在集合中的顺序,如果compareTo方法返回1,则放在当前比较元素的后边,否则放前边。
下面的代码演示使用Comparetor来排序元素
import java.util.Comparator; import java.util.Iterator; import java.util.TreeSet; class Student implements Comparable{ String name; int age; public Student(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } @Override public int compareTo(Object o) { if (!(o instanceof Student)) { throw new RuntimeException(); } Student s=(Student)o; if (this.age>s.getAge()) { return 1; }else if (this.age==s.getAge()) { return this.name.compareTo(s.name); } return -1; } } class MyComparator implements Comparator { @Override public int compare(Object o1, Object o2) { Student s1=(Student)o1; Student s2=(Student)o2; int ret=s1.getName().compareTo(s2.getName()); if (ret==0) { return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge())); } return ret; } } public class TreeSetDemo { public static void main(String[] args) { demo2(); } public static void demo2(){ TreeSet ts=new TreeSet(new MyComparator()); ts.add(new Student("lisi01", 56)); ts.add(new Student("lisi02", 34)); ts.add(new Student("lisi03", 34)); ts.add(new Student("lisi04", 12)); Iterator it=ts.iterator(); while(it.hasNext()){ Student s=(Student)it.next(); System.out.println(s.getName()+"的年龄是:"+s.getAge()); } } }
下面的代码演示:在HashSet中存储字符串,并按字符串长度排序:
import java.util.Comparator; import java.util.Iterator; import java.util.TreeSet; public class TreeSetDemo2 { public static void main(String[] args) { TreeSet hs=new TreeSet(new Comparator() { @Override public int compare(Object o1, Object o2) { String s1=(String)o1; String s2=(String)o2; int ret=new Integer(s1.length()).compareTo(new Integer(s2.length())); if (ret==0) { return s1.compareTo(s2); } return ret; } }); hs.add("a"); hs.add("abd"); hs.add("abc"); hs.add("ab"); hs.add("abcd"); Iterator it=hs.iterator(); while(it.hasNext()){ System.out.println(it.next()); } } }
本节共学习了2个接口(Comparable和Comparator),2个方法(compareTo和compare),1个类TreeSet,本章到这里共学习5个类,6个接口,43个方法。
下面是到本节结束为止学习的内容的UML类图:

转自:http://blog.csdn.net/Joven0/article/details/44890479