1,集合类
·为什么出现集合类?
面向对象语言对事物的体现都是以对象的方式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的方式。
·数组和集合类同是容器,有何不同?
数组虽然也可以存储对象,但长度是固定的,集合长度是可变的,数组中可以存储基本数据类型,集合只能存储对象。
·集合类的特点
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
![](https://img-my.csdn.net/uploads/201303/29/1364545492_2567.jpg)
4,List:
结果:
把上面的方法封装一下
练习:
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
去除ArrayList中的重复元素。
结果:
7, HashSet :
Person.java
结果:
Student.class
TreeSetDemo2.class
MyCompare.class
·为什么出现集合类?
面向对象语言对事物的体现都是以对象的方式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的方式。
·数组和集合类同是容器,有何不同?
数组虽然也可以存储对象,但长度是固定的,集合长度是可变的,数组中可以存储基本数据类型,集合只能存储对象。
·集合类的特点
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
因为每一个容器对数据的存储方式都有不同,这个存储方式称之为 数据结构。
2,共性方法:
import java.util.ArrayList;
public class CollectionDemo {
/**
add 方法的参数类型是Object,一边与接受任意类型的对象。
集合中存数的都是集合的引用(地址)
*/
public static void main(String[] args) {
//创建一个集合容器,使用Collection接口的子类,ArrayList。
ArrayList al=new ArrayList();
//1,添加元素
al.add("java01"); //Object obj
al.add("java02");
al.add("java03");
al.add("java04");
// System.out.println(al);
//2,删除元素
al.remove("java02");
// al.clear();
// System.out.println(al);
//3,获取元素个数,集合长度
System.out.println("size:"+al.size());
//4,判断元素
System.out.println( al.contains("java03"));
al.isEmpty();//是否为空。
ArrayList a=new ArrayList();
a.add("java01"); //Object obj
a.add("java05");
a.add("java06");
a.add("java07");
//取交集
al.retainAll(a);
System.out.println( al);
System.out.println( a);
}
3,迭代器:
就是集合的取出元素的方式。
![](https://img-my.csdn.net/uploads/201303/29/1364545492_2567.jpg)
Iterator it= al.iterator(); //获取迭代器,用于取出数组中的元素。
while(it.hasNext())
{
System.out.println(it.next());
}
//换成优异的写法
for(Iterator it=al.iterator();it.hasNext();)
{
System.out.println(it.next());
}
4,List:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
Collection
|--List:元素是有序的,元素可以重复,因为该集合体系有索引
|--ArrayList:底层的数据结构使用的是数组结构。 特点:查询速度很快。 但是增删稍慢。 线程不同步。
|--LinkedList:底层使用的是链表数据结构 特点:增删很快,查询稍慢。
|--Vector:底层是数组数据结构。JDK 1.0.。。 Vector是同步的
|--Set:元素是无序的,元素不可以重复。
List 特有方法:
凡是可以操作角标的方法都是该体系特有的方法。
增:add(index,element);
addAll(index,Collection)
删: remove(index);
改:set(index,element)
查:get(index);
subList(from,to)
listIterator();
List集合特有的迭代器,ListIterator是Iterator的子接口。
在迭代时,不可以通过集合对象的方法操作集合中的元素,会发生ConcurrentModificationException异常,
所以在迭代时,只能用迭代器的方法操作元素,可是Iterator方法是有限的,只能对元素进行判断,去除,删除的操作。
如果想要其他操作入添加,修改等,就需要使用其子接口 ListIterator。
该接口只能通过List集合的ListIterator方法获取
*/
public class ListDemo {
public static void main(String[] args) {
ArrayList al=new ArrayList();
//添加元素
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
//在指定位置添加元素
al.add(1, "java09");
System.out.println(al); //[java01, java09, java02, java03, java04]
//删除指定位置的元素
al.remove(2);
//修改元素
al.set(3, "c#");
//通过角标获取元素。
// al.get(2);
//获取所有元素
for(int x=0;x<al.size();x++)
{
System.out.println(al.get(x));
//java01
//java09
//java03
//c#
}
Iterator it=al.iterator();
while(it.hasNext())
{
System.out.println(it.next());
//java01
//java09
//java03
//c#
}
//通过indexof获取对象位置
System.out.println(al.indexOf("java09"));
//1
List sub=al.subList(1, 3);
System.out.println(sub);
//[java09, java03]
}
}
5,ListIterator:
public class ListDemo {
public static void main(String[] args) {
ArrayList al=new ArrayList();
//添加元素
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
/*
Iterator it=al.iterator();
while(it.hasNext())
{
Object obj=it.next();
if(obj.equals("java02"))
//这里不可以同时进行 List的操作。会引发并发错误!
{
it.remove(); //将java02的引用从集合中删除了。
//不可以执行添加操作。
//所以就有了列表迭代器。
}
System.out.println("obj="+obj); //但是java02 还在被obj使用
}
System.out.println(al);
*/
System.out.println(al);
ListIterator li=al.listIterator();
System.out.println("next---"+li.hasNext());
System.out.println("Previous---"+li.hasPrevious());
while(li.hasNext())
{
Object obj=li.next();
if(obj.equals("java02"))
{
//li.add("java009");
li.set("java006");
}
}
System.out.println(al);
System.out.println("next---"+li.hasNext());
System.out.println("Previous---"+li.hasPrevious());
while(li.hasPrevious())
{
System.out.println("Pre:"+li.previous());
}
}
}
结果:
6,LinkedList:
import java.util.LinkedList;
public class LinkedListDemo {
/**
* LinkedList 特有方法:
* addFirst();
* addLast();
*
* getFirst();
* getLast(); //获取元素,但不删除元素。
* 如果集合中没有元素会出现NoSuchElementException
*
* removeFirst()
* removeLast() //获取元素,但元素被删除。
*如果集合中没有元素会出现NoSuchElementException
*
*在JDK1.6出现了替代方法,
*
*offerFirst();
*offerLast();
*
*peekFirst();
*peekLast();
*如果集合中没有元素则返回null。
*pollFirst();
*pollLast();
*如果集合中没有元素则返回null。
*/
public static void main(String[] args) {
LinkedList linked=new LinkedList();
linked.addFirst("java01");
linked.addFirst("java02");
linked.addFirst("java03");
linked.addFirst("java04");
//linked.addLast(e)
System.out.println(linked);//[java04, java03, java02, java01]
System.out.println(linked.getFirst()); //java04
System.out.println(linked.getLast());//java01
System.out.println(linked.removeFirst());//java04
System.out.println(linked.size());//3
//获取
while(!linked.isEmpty())
{
System.out.println( linked.removeFirst());
}
}
}
把上面的方法封装一下
import java.util.LinkedList;
public class Queue {
/**
* 使用LinkedList模拟堆栈或者队列的数据结构。
* 堆栈:先进后出 (如同一个杯子)
* 队列:先进先出。(如同一个水管)
*/
private LinkedList link;
Queue()
{
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) {
Queue qu=new Queue();
qu.myAdd("JAVA01");
qu.myAdd("JAVA02");
qu.myAdd("JAVA03");
qu.myAdd("JAVA04");
while (!qu.isNull())
{
System.out.println(qu.myGet());
//JAVA01
//JAVA02
//JAVA03
//JAVA04
}
}
}
练习:
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
去除ArrayList中的重复元素。
import java.util.ArrayList;
import java.util.Iterator;
public class ArrayListTest {
/**
* @param args
*/
public static void main(String[] args) {
ArrayList al=new ArrayList();
al.add("Java01");
al.add("Java01");
al.add("Java02");
al.add("Java02");
al.add("Java03");
al.add("Java03");
al.add("Java01");
al.add("Java04");
al=singleElement(al);
System.out.println(al);
}
public static ArrayList singleElement(ArrayList al)
{
//定义一个临时容器
ArrayList newAl=new ArrayList();
Iterator it=al.iterator();
while(it.hasNext())
{
Object obj=it.next();
if(!newAl.contains(obj))
{
newAl.add(obj);
}
}
return newAl;
}
}
结果:
![](https://img-my.csdn.net/uploads/201303/31/1364733813_9227.jpg)
7, HashSet :
HashSetDemo.java
import java.util.HashSet;
import java.util.Iterator;
public class HashSetDemo {
/**
* Set 元素是无序(存入和取出的顺序不一定一致),元素不可以重复。 Set 集合的功能和Collection是一致的。
* |--HashSet:底层数据结构是哈希表。线程时非同步的。
* HashSet是如何保证元素唯一性的呢?是通过元素的两个方法:HashCode 和 equals来完成的。
* 如果元素的HashCode值相同,才会判断equals是否为true。
* 如果元素的hashcode值不同,不会调用equals。
*
* 注意:对于判断元素是否存在,以及删除,依赖的是元素hashCode和 equals方法。
* |--TreeSet:可以对Set集合中的元素排序。
* Set集合功能和Collection是一致的。
*/
public static void main(String[] args) {
HashSet hs = new HashSet();
// hs.add("java01");
// hs.add("java02");
// hs.add("java03");
// System.out.println(hs.add("java04"));//true
// System.out.println(hs.add("java04"));//false
hs.add(new Person("zhangsan", 20));
hs.add(new Person("lisi", 19));
hs.add(new Person("wangwu", 18));
hs.add(new Person("zhangsan", 20));
//hs.contains();
//hs.remove();
Iterator it = hs.iterator();
while (it.hasNext()) {
Person P=(Person )it.next();
System.out.println(P.getName());
//java04
//java02
//java03
//java01
}
}
}
Person.java
public class Person {
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object obj) {
//super.equals(obj);
if(! (obj instanceof Person))
return false;
Person p=(Person)obj;
System.out.println(this.name+"...equals..."+p.name);
return this.name.equals(p.name)&&(this.age==p.age);
}
public int hashCode()
{
//return 60;
System.out.println(this.name+"~~~~~hashcode");
return name.hashCode()+age*25;
}
结果:
![](https://img-my.csdn.net/uploads/201304/01/1364811920_2977.jpg)
7,TreeSet:
TreeSetDemo.class
import java.util.Iterator;
import java.util.TreeSet;
public class TreeSetDemo {
/*|--TreeSet:可以对Set集合中的元素排序。
底层数据结构是二叉树。保证元素唯一性的依据是: CompareTo 方法 return 0;
TreeSet排序第一种方式,覆盖CompareTo方法, 这种方式也称为元素的自然循序,或者叫默认循序。
TreeSet排序第二种方式,当元素不具备比较性时,或者具备的比较性不是所需要的,这时就需要让集合自身具备比较性。
在集合初始化时就有了比较方式。
*/
/**
*需求:往TreeSet中存储自定义对象学生,
*按照学生的年龄进行排序。
*排序时,当主要条件相同时,一定要判断次要条件。
*/
public static void main(String[] args) {
TreeSet ts=new TreeSet();
ts.add(new Student("lisi001",18));
ts.add(new Student("lisi002",19));
ts.add(new Student("lisi003",20));
ts.add(new Student("lisi004",16));
ts.add(new Student("lisi006",21));
ts.add(new Student("lisi005",21));
Iterator it =ts.iterator();
while(it.hasNext())
{
Student stu=(Student)it.next();
System.out.println(stu.getName()+"-------"+stu.getAge());
//result:
//lisi004-------16
//lisi001-------18
//lisi002-------19
//lisi003-------20
//lisi005-------21
//lisi006-------21
}
}
}
Student.class
import javax.management.RuntimeErrorException;
public class Student implements Comparable { // 该接口强制让学生具有比较性
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public int compareTo(Object o) {
if (!(o instanceof Student)) {
throw new RuntimeException("不是学生对象");
}
Student s = (Student) o;
if (this.age > s.age)
return 1;
else if (this.age == s.age)
//return 0;
return this.name.compareTo(s.name);//String 类已经实现了CompareTo接口。
else
return -1;
// 直接 return 1; //按存入顺序 向树右边存储
// 直接 return -1; //按存入倒序 向树左边存储
}
}
TreeSetDemo2.class
import java.util.Iterator;
import java.util.TreeSet;
/*
* 当元素自身不具备比较性时,或者具备的比较性不是所需的。
* 这时需要让容器自身具备比较性。
* 定义一个比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。
* 当2种排序都存在时,以比较器为主,
* 定义一个类:实现Comparator,覆盖Compare 方法。
*/
//需求:按姓名排序。
public class TreeSetDemo2 {
public static void main(String[] args) {
TreeSet ts=new TreeSet(new MyCompare());
ts.add(new Student("lisi001",18));
ts.add(new Student("lisi002",19));
ts.add(new Student("lisi003",20));
ts.add(new Student("lisi004",16));
ts.add(new Student("lisi004",18));
Iterator it =ts.iterator();
while(it.hasNext())
{
Student stu=(Student)it.next();
System.out.println(stu.getName()+"-------"+stu.getAge());
// result:
// lisi001-------18
// lisi002-------19
// lisi003-------20
// lisi004-------16
}
}
}
MyCompare.class
import java.util.Comparator;
public class MyCompare implements Comparator {
@Override
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;
}
}