1、概述
1.1 集合类概述
对象用于封装特有数据,对象多了需要存储;如果对象的个数不确定,就使用集合容器进行存储。1.2 集合特点:
(1)用于存储对象的容器。
(2)集合的长度是可变的。
(3)集合中不可以存储基本数据类型值。- 1.3 java util包中的集合种类
集合框架中为什么有这么多的容器?
集合容器因为内部的数据结构不同,有多种具体容器。不断的向上抽取,就形成了集合框架。
2、集合框架中的共性方法
- 2.1 添加
boolean add(E o)
确保此 collection 包含指定的元素(可选操作)。
boolean addAll(Collection c)
将指定 collection 中的所有元素都添加到此 collection 中。
import java.util.*;
class ArrayListDemo
{
public static void main(String[] args)
{
ArrayList al1=new ArrayList(); //创建一个集合容器,使用Collection接口的子类ArrayList
al1.add("java01");
al1.add("java02");
ArrayList al2=new ArrayList();
al2.add("java03");
al2.add("java04");
al1.addAll(al2);
System.out.println("addAll(al2)="+al1);
}
}
- 2.2 删除
boolean removeAll(Collection c)
移除此 collection 中那些也包含在指定 collection 中的所有元素。
boolean remove(Object o)
从此 collection 中移除指定元素的单个实例,如果存在的话。
public static void main(String[] args)
{
ArrayList al1=new ArrayList();
al1.add("java01");
al1.add("java02");
ArrayList al2=new ArrayList();
al2.add("java03");
al2.add("java04");
al1.addAll(al2);
al1.remove("java01");
System.out.println("remove(java01)="+al1);
al1.removeAll(al2);
System.out.println("removeAll(al2)="+al1);
}
- 2.3 判断
boolean isEmpty()
如果此 collection 不包含 元素,则返回 true。
boolean contains(Object o)
如果此 collection 包含指定的元素,则返回 true。
boolean containsAll(collection c)
是否包含指定的字符数组
public static void main(String[] args)
{
ArrayList<String> al1=new ArrayList<String>();
al1.add("java01");
al1.add("java02");
System.out.println("contains(java01)="+al1.contains("java01"));
System.out.println("isEmpty="+al1.isEmpty());
}
- 2.4 取出
boolean hasNext()
如果仍有元素可以迭代,则返回 true。
E next()
返回迭代的下一个元素。
public interface Iterator
对 collection 进行迭代的迭代器。
import java.util.*;
class ArrayListDemo
{
public static void main(String[] args)
{
ArrayList<String> al1=new ArrayList<String>();//创建一个集合容器,使用Collection接口的子类ArrayList
al1.add("java01");
al1.add("java02");
al1.add("java03");
al1.add("java04");
Iterator it=al1.iterator();
while(it.hasNext())//判断是否仍有元素可以迭代返回
{
System.out.println(it.next());//返回迭代的下一个元素
}
}
}
其他方法:
for(int x=0;x<x.al.size();x++)
{
System.out.println(al.get(x));
}
- 2.5 其他功能-取交集
public static void main(String[] args)
{
ArrayList<String> al1=new ArrayList<String>();
al1.add("java01");
al1.add("java02");
ArrayList<String> al2=new ArrayList<String>();
al2.add("java01");
al2.add("java04");
al1.retainAll(al2);
System.out.println(al1);
}
3、List 集合
- 3.1 List概述
(1) List集合是有序的,因为集合体系有索引,所以元素可以重复。包括以下三种:
–>ArrayList:数组结构,线程不同步,查询快,但增删慢。
–>LinkedList:链表数据结构,查询慢,增删快。
–>Vector:底层数组数据结构,线程同步。
(2)List集合的共性方法
凡是可以操作角标的都是该体系特有的方法。
(增):
void add(int index,E element)
在列表的指定位置插入指定元素(可选操作)。
boolean addAll(int index,Collection c)
将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。
(删):
remove(int index)
移除列表中指定位置的元素(可选操作)。
(改):
set(int index,E element)
用指定元素替换列表中指定位置的元素(可选操作)。
(查):
get(int index)
返回列表中指定位置的元素。
subList(int fromIndex,int toIndex)
返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图
import java.util.*;
class ListDemo
{
public static void main(String[] args)
{
List<String> list =new ArrayList<String>();
list.add("java01");
list.add("java02");
list.add("java03");
System.out.println(list);
/***************************添加*****************************/
list.add(1,"java04");
System.out.println("list.add="+list);
/***************************移除*****************************/
list.remove(3);
System.out.println("list.remove="+list);
/***************************修改*****************************/
System.out.println("list.set="+list.set(1,"java001"));
System.out.println("list.setedget="+list.get(1));
/***************************获取*****************************/
System.out.println("list.get="+list.get(2));
/***************************获取子列表************************/
System.out.println("subList="+list.subList(1,3));
}
}
(取出):
listIterator(int index)
返回列表中元素的列表迭代器(以正确的顺序),从列表的指定位置开始。ListIterator是List集合特有的迭代器,是Iterator的子接口。在迭代时,不可以通过集合对象的方法操作集合中的元素。因为会发生ConcurrentModificationException异常。所以在迭代器时,只能用迭代器的方法操作元素。可是Iterator方法是有限的,只能对元素进行判断,取出,删除的操作。如果想要其他的操作,如添加、修改等,就需要使用其子接口:ListIterrator。该接口只能通过List集合的ListIterator方法获取。
ListIterator特有的方法
add(obj);//增加
set(obj);//修改为obj
hasPrevious();//判断前面有没有元素
previous();//取前一个元素
事例说明:
import java.util.*;
class ListIteratorDemo
{
public static void main(String[] args)
{
List<String> list = new ArrayList<String>();
list.add("abc1");
list.add("abc2");
list.add("abc3");
System.out.println("原来list:"+list); //获取列表迭代器对象
ListIterator<String> it = list.listIterator();
while(it.hasNext())
{
Object obj = it.next();
it.add("abc9");
}
System.out.println("添加完后list:"+list);
/*********************************************************/
System.out.println("hasNext:"+it.hasNext()); //hasNext()正向遍历列表,若列表叠加器有多个元素,则返回true
System.out.println("hasPrevious:"+it.hasPrevious());//hasPrevious()逆向遍历列表
while(it.hasPrevious())
{
System.out.println("previous:"+it.previous());
}
}
}
- 3.2 ArrayList集合
/*
需求:去除ArrayList集合中的重复元素
*/
import java.util.*;
class ArrayListTest1
{
public static ArrayList SingleElements(ArrayList al)//原来的集合
{
ArrayList<String>newal=new ArrayList<String>();//定义新的集合
Iterator it=al.iterator();
while (it.hasNext())
{
Object obj=it.next();
if (!newal.contains(obj))
{
newal.add(obj);
}
}
return newal;
}
public static void main(String[] args)
{
ArrayList<String> al=new ArrayList<String>();
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java03");
System.out.println(al);
al=SingleElements(al);
System.out.println(al);
}
}
/*将自定义的对象作为元素存在ArrayList集合中,并去除重复的元素。比如存人为对象,姓名。年龄相同视为同一个人*/
import java.util.*;
/*定义Person类*/
class Person
{
private String name;
private int age;
Person(String name,int age)
{
this.name=name;
this.age=age;
}
public String getName()
{
return name;
}
public void setName(String n)
{
name=n;
}
public int getAge()
{
return age;
}
public void setAge(int a)
{
age=a;
}
/*原来Person类中默认的equals方法是比较的对象,所以要重新复写功能,把定义为比较年龄和年龄*/
public boolean equals(Object obj)
{
if(!(obj instanceof Person))//如果比较的对象不一样的时候,就会报错,严谨的时候可以抛出异常
return false;
Person p=(Person)obj;//向上转型
return this.name.equals(p.name)&&this.age==p.age;//比较的是姓名和年龄
}
}
class ArrayListTest2
{
public static void main(String[] args)
{
ArrayList al=new ArrayList();
al.add(new Person("LiMing01",21));
al.add(new Person("LIMIng02",22));
al.add(new Person("LIMIng02",22));
al.add(new Person("LiMing03",23));
al.add(new Person("LiMing04",25));
al.add(new Person("LiMing04",25));
al=SingleElements(al);
Iterator it=al.iterator();
while(it.hasNext())
{
Object obj=it.next();
Person p=(Person)obj;
System.out.println(p.getName()+"~~~"+p.getAge());
}
}
//定义原有的集合,接受没有去重复的元素集合
public static ArrayList SingleElements(ArrayList al)
{
ArrayList newal=new ArrayList();//定义一个新的容器,来接受去重复的元素集合
Iterator it=al.iterator();
while (it.hasNext())
{
Object obj=it.next();
if(!newal.contains(obj))//boolean contains(Object obj) 当且仅当此collection至少包含一个满足(o==null?e==null:o.equals(e))//o为空的时候e为空,o不为空的时候就调用equals方法
newal.add(obj);
}
return newal;
}
}
- 3.3 Vector中的枚举
枚举是Vector特有的方式,发现枚举和迭代器很像,其中枚举和迭代一样,但是枚举方法名称方法过长而不使用。
public Enumeration elements()
返回此向量的组件的枚举。
public interface Enumeration
实现 Enumeration 接口的对象,它生成一系列元素,一次生成一个。连续调用 nextElement 方法将返回一系列的连续元素。
boolean hasMoreElements()
测试此枚举是否包含更多的元素。
nextElement()
如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素。
注:此接口的功能与 Iterator 接口的功能是重复的。此外,Iterator 接口添加了一个可选的移除操作,并使用较短的方法名。新的实现应该优先考虑使用 Iterator 接口而不是 Enumeration 接口。
import java.util.*;
class VectorDemo
{
public static void main(String[] args)
{
Vector<String> v=new Vector<String>();
v.add("java01");
v.add("java02");
v.add("java03");
v.add("java04");
Enumeration en=v.elements();
while(en.hasMoreElements())
{
System.out.println(en.nextElement());
}
}
}
- 3.4 LinkedList集合
(1)LinkedList集合的各种方法
(增):
public void addFirst(E o)
将给定元素插入此列表的开头。
public void addLast(E o)
将给定元素追加到此列表的结尾。
(取):
public E getFirst()
返回此列表的第一个元素。
public E getLast()
返回此列表的最后一个元素。
(删):
public E removeFirst()
移除并返回此列表的第一个元素。
public E removeLast()
移除并返回此列表的最后一个元素。
/*******************************************/
JDK1.6后出现了新的替代方法
/*******************************************/
public boolean offerFirst(E e)
在此列表的开头插入指定的元素。
public boolean offerLast(E e)
在此列表末尾插入指定的元素。
public E peekFirst()
获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。
public E peekLast()
获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。
public E pollFirst()
获取并移除此列表的第一个元素;如果此列表为空,则返回 null。
public E pollLast()
获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。
import java.util.*;
class LinkedListDemo
{
public static void main(String[] args)
{
LinkedList<String> link=new LinkedList<String>();
link.addFirst("java01");
link.addFirst("java02");
link.addFirst("java03");
link.addFirst("java04");
Sop("addFirst="+link);
LinkedList<String> link1=new LinkedList<String>();
link1.addLast("java01");
link1.addLast("java02");
link1.addLast("java03");
link1.addLast("java04");
Sop("addlast="+link1);
}
/***********************************************************/
Sop("getFirst()="+link.getFirst());
Sop("getLast()="+link.getLast());
/***********************************************************/
Sop("removeFirst()="+link.removeFirst());
Sop("removeFirst()后="+link.getFirst());
Sop(link);
/***********************************************************/
link.offerFirst("哈哈");
Sop(link);
/*****************************************************/
public static void Sop(Object obj)
{
System.out.println(obj);
}
}
(2)LinkedList集合的练习
/************************************************************
模拟一个堆栈的或队列的数据结构
堆栈:先进后出(杯子)
队列:先进后出(水管)
************************************************************/
import java.util.*;
class DuiLie
{
private LinkedList link;
DuiLie()
{
link=new LinkedList();
}
public void myAdd(Object obj)
{
link.addFirst(obj);
}
public Object myGet()
{
return link.removeLast();
}
public boolean isNull()
{
return link.isEmpty();
}
public static void main(String[] args)
{
DuiLie dl=new DuiLie();
dl.myAdd("java01");
dl.myAdd("java02");
dl.myAdd("java03");
while (!dl.isNull())
{
System.out.println(dl.myGet());
}
}
}
4、 Set集合
set集合中元素是无序的,元素不可重复
- 4.1 HashSet集合
(1)HashSet集合底层结构为哈希表
class Demo
{
}
class HashSetDemo1
{
public static void main(String[] args)
{
Demo d1=new Demo();
Demo d2=new Demo();
Sop(d1);
Sop(d2);//打印的是ToString方法
}
public static void Sop(Object obj)
{
System.out.println(obj);
}
}
(2)
改进:为了提高程序的高效性,假若hashCode值一样才回调用equals方法,所以对象a1 a3的hashCode值若不一样就无需调用其中的equals方法。
注意:ArrayList集合判断元素是否存在依赖的是equals方法。HashSet对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。
/*
往hashSet集合中存入自定对象
姓名和年龄相同为同一个人,重复元素。去除重复元素
思路:1、对人描述,将人的一些属性等封装进对象
2、定义一个HashSet容器,存储人对象
3、取出
*/
import java.util.*;
class Person//定义Person类
{
private String name;
private int age;
Person(String name,int age)
{
this.name=name;
this.age=age;
}
public int getAge()
{
return age;
}
public void setAge(int a)
{
a=age;
}
public String getName()
{
return name;
}
public void setName(String n)
{
n=name;
}
public boolean equals(Object obj)
{//复写equals方法
if (!(obj instanceof Person))
return false;
Person p=(Person)obj;
return this.name.equals(p.name)&&this.age==p.age;
}
public int hashCode()
{//复写HashCode方法
return name.hashCode()+age*39;//有许多没必要比较的,本来姓名不一样,让他们地址值不一样就好
}
}
class HashSetDemo5
{
public static void main(String[] args)
{
HashSet hs=new HashSet();
hs.add(new Person("a1",11));
hs.add(new Person("a1",11));
hs.add(new Person("a2",12));
hs.add(new Person("a3",13));
hs.add(new Person("a4",14));
hs.add(new Person("a4",14));
if(hs.contains(new Person("a2",12)))
hs.remove(new Person("a3",13));
Iterator it=hs.iterator();
while(it.hasNext())
{
Object obj=it.next();
Person p=(Person)obj;
System.out.println(p.getName()+"++++"+p.getAge());
}
}
}
- 4.2 TreeSet集合
底层的数据结构为二叉树结构。可对Set集合中的元素进行排序,是因为:TreeSet类实现了Comparable接口,该接口强制让增加到集合中的对象进行了比较,需要复写compareTo方法,才能让对象按指定需求(如人的年龄大小比较等)进行排序,并加入集合。java中的很多类都具备比较性,其实就是实现了Comparable接口。
注意:排序时,当主要条件相同时,按次要条件排序。
(1)
public interface Comparable
此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。
ClassCastException -
如果指定对象的类型不允许它与此对象进行比较。
int compareTo(T o)
比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
/************************************************************
第一种排序:使用TreeSet集合进行对象存储,并进行自然顺序的排序和比较。
************************************************************/
import java.util.*;
class Student implements Comparable//强制学生具有比较性
{
private int age;
private String name;
Student(String name,int age)
{
this.name=name;
this.age=age;
}
public int getAge()
{
return age;
}
public void setAge(int a)
{
a=age;
}
public String getName()
{
return name;
}
public void setName(String n)
{
n=name;
}
public int compareTo(Object obj)
{
if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student stu=(Student)obj;
System.out.println(this.name+"*****"+stu.name);
if(this.age>stu.age)
return 1;
if(this.age==stu.age)
return(this.name.compareTo(stu.name));
return -1;
}
}
class TreeSetDemo
{
public static void main(String[] args)
{
TreeSet ts=new TreeSet();
ts.add(new Student("lisi01",12));
ts.add(new Student("lisi02",11));
ts.add(new Student("lisi03",17));
ts.add(new Student("lisi05",13));
ts.add(new Student("lisi08",11));
Iterator it=ts.iterator();
while(it.hasNext())
{
Object obj=it.next();
Student stu=(Student)obj;
System.out.println(stu.getName()+"**"+stu.getAge());
}
}
}
(2)
public interface Comparator
强行对某个对象 collection 进行整体排序 的比较函数。
int compare(T o1,T o2)
比较用来排序的两个参数。根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或正整数。
boolean equals(Object obj)
指示某个其他对象是否“等于”此 Comparator。
/***********************************************************
第二种排序:comparator的排序.先实现compatator接口,覆盖compare接口
当两种排序共存时,以比较器为主
先按照姓名排序,后按照年龄排序
************************************************************/
import java.util.*;
class Student implements Comparable
{
private int age;
private String name;
Student(String name,int age)
{
this.name=name;
this.age=age;
}
public int getAge()
{
return age;
}
public void setAge(int a)
{
a=age;
}
public String getName()
{
return name;
}
public void setName(String n)
{
n=name;
}
public int compareTo(Object obj)
{
if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student stu=(Student)obj;
System.out.println(this.name+"*****"+stu.name);
if(this.age>stu.age)
return 1;
if(this.age==stu.age)
return(this.name.compareTo(stu.name));
return -1;
}
}
class MyCompare implements Comparator
{
public int compare(Object o1,Object o2)
{
Student s1=(Student)o1;
Student s2=(Student)o2;
int num=s1.getName().compareTo(s2.getName());
if(num==0)
return s1.getAge()-s2.getAge();
return num;
}
}
class TreeSetDemo
{
public static void main(String[] args)
{
TreeSet ts=new TreeSet(new MyCompare());
ts.add(new Student("lisi01",12));
ts.add(new Student("lisi02",11));
ts.add(new Student("lisi03",17));
ts.add(new Student("lisi05",13));
ts.add(new Student("lisi08",11));
ts.add(new Student("lisi08",13));
Iterator it=ts.iterator();
while(it.hasNext())
{
Object obj=it.next();
Student stu=(Student)obj;
System.out.println(stu.getName()+"**"+stu.getAge());
}
}
}
(3)TreeSet练习
/****************************************************
要求:按照字符串的长度排序
/****************************************************/
import java.util.*;
class StringLengthComparator implements Comparator
{
public int compare(Object o1,Object o2)
{
String s1=(String)o1;
String s2=(String)o2;
/*****************************************************
if(s1.length()>s2.length())
return 1;
if(s1.length()<s2.length())
return -1;
return 0;
这种方式书写的话,假若字符串的长度是相同的,
那么就认为对象相同,不会被打印。
********************************************************/
int num=new Integer(s1.length()).compareTo(new Integer(s2.length()));
if(num==0)
return s1.compareTo(s2);
return num;
}
}
class TreeSetDemo
{
public static void main(String[] args)
{
TreeSet ts=new TreeSet(new StringLengthComparator());
ts.add("asfdfdggg");
ts.add("fdf");
ts.add("vvv");
ts.add("dfdgdgseeeee");
ts.add("f");
Iterator it=ts.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
}