Java笔记--集合

1.用来存储对象的一种常见方式

 

2.集合的特点

(1)集合只用来存储对象

(2)集合的长度是可变的

(3)集合可以存储不同类型的对象

 

3.为什么会出现这么多的容器呢

因为每一个容器对数据的存储方式都不同,这个存储方式就称为数据结构

 

4.集合中存储的都是对象的引用(地址)

 

5.迭代器(通常用来遍历集合)

其实就是集合取出元素的方式

取出方式被定义成了内部类,定义在集合的内部,这样取出方式就可以直接访问集合中的元素,而每一个容器的数据结构不同,所以取出的动作细节也不一样,但是都有共性内容----判断和取出,那么就可以将共性抽取。这些内部类都符合一个规则,该规则就是Iterator。

如何获取集合的取出对象呢?

通过一个对外提供的方法iterator();

 

实例

import java.util.*;

 

class CollectionDemo

{

public static void main(String[] args)

{

ArrayList al = new ArrayList();

al.add("java 01");

al.add("java 02");

al.add("java 03");

al.add("java 04");

 

for(Iterator it = al.iterator();it.hasNext();)

{

sop(it.next());

}

}

 

public static void sop(Object obj)

{

System.out.println(obj);

}

}

 

6.集合框架

Collection

|--List:元素是有序的,元素可以重复,因为该集合体系中有索引

特有方法:凡是可以操作角标的方法都是该体系的特有方法

|--ArrayList:底层的数据结构是数组数据结构,特点是查询速度很快,但是

增删稍慢,线程不同步

|--LinkedList:底层使用的是链表数据结构,特点:增删速度很快,查询稍慢

|--Vector:底层是数组数据结构,线程同步。被ArrayList代替了

|--Set:元素是无序的(存入和取出的顺序不一定一致),元素不可以重复

Set集合的功能和Collection是一致的,

|--HashSet:底层数据结构是哈希表,线程不同步

HashSet是如何保证元素的唯一性的呢?

是通过元素的两个方法,hashCode和equals来完成的

如果元素的HashCode值相同,才会判断equals是否为true

如果元素的HashCode值不同,则不会判断equals。

|--TreeSet:可以对Set集合中的元素进行排序

底层结构是二叉树

保证元素唯一性的依据:compareTo方法return 0

TreeSet排序的第一种方式:让元素自身具备比较性。

元素需要实现Comoparable接口,覆盖compareTo方法

TreeSet排序的第二种方式:当元素自身不具备比较性,或者具备的

比较性不是所需要的。这时需要让容器自身具备比较性。定义了比

较器,将比较器对象作为参数传递给TreeSet集合的构造函数。

当两种排序都存在的时候,以比较器为主

定义一个类,实现Comparator接口,覆盖compare方法,将该类对

象作为参数传递给TreeSet集合的构造器

注意:排序时,当主要条件相同时,一定要判断下次要条件

 

 

7.ListIterator是Iterator的子接口,是List集合特有的迭代器,在迭代的时候,不可以通过对象的方法操作集合中的元素,因为会发生ConcurrentModificationException并发修改异常,所以在迭代时,只能用迭代器的方法操作元素,可是Iterator方法是有限的,只能对元素进行判断、取出、删除的操作,如果想要进行其它的操作,如添加、修改等就需要使用其子接口ListIterator。该接口只能通过List集合的listIterator方法获取。

 

import java.util.*;

 

class CollectionDemo

{

public static void main(String[] args)

{

ArrayList al = new ArrayList();

al.add("java 01");

al.add("java 02");

al.add("java 03");

al.add("java 04");

ListIterator li = al.listIterator();

 

while(li.hasNext())

{

Object obj = li.next();

 

if(obj.equals("java 02"))

{

li.set("java 10"); //替换元素

//li.add("java 10"); //添加一个新的对象引用

}

}

}

 

public static void sop(Object obj)

{

System.out.println(obj);

}

}

 

8.枚举是vector特有的取出方式

枚举和迭代器很像,其实枚举和迭代是一样的,因为枚举的名称以及方法都过长,所以被迭代器取代了,枚举就郁郁而终了。

 

class VectorDemo

{

public static void main(String[] args)

{

Vector ve = new Vector();

 

ve.add("java 01");

ve.add("java 02");

ve.add("java 03");

ve.add("java 04");

 

Enumeration en = ve.elements();

 

while(en.hasMoreElements())

{

System.out.println(en.nextElement());

}

}

}

 

9.LinkedList的特有方法

addFirst();

addLast();

 

//获取元素,但不删除元素,如果集合中没有元素,

//会出现NoSuchElementException异常

getFirst();

getLast();

 

//获取元素,但元素被删除。,如果集合中没有元素,

//会出现NoSuchElementException异常

removeFirst();

removeLast();

 

在JDK1.6出现了替代方法

offerFirst();

offerLast();

 

//获取元素,但不删除元素,如果集合中没有元素,

//会返回null

peekFirst();

peekLast();

 

//获取元素,但元素被删除。,如果集合中没有元素,

//会返回null

pollFirst();

pollLast();

 

10.用LinkedList模拟一个队列或堆栈的数据结构

import java.util.*;

 

class MyQueue

{

private LinkedList link;

 

MyQueue()

{

link = new LinkedList();

}

 

public void myAdd(Object obj)

{

link.addFirst(obj);

}

 

public Object myGet()

{

//return link.removeLast(); //模拟一个队列

return link.removeFirst(); //模拟一个堆栈

}

 

public boolean isNull()

{

return link.isEmpty();

}

 

}

 

 

class LinkedListDemo

{

public static void main(String[] args)

{

MyQueue myQueue = new MyQueue();

 

myQueue.myAdd("java 01");

myQueue.myAdd("java 02");

myQueue.myAdd("java 03");

myQueue.myAdd("java 04");

while(!myQueue.isNull())

{

System.out.println(myQueue.myGet());

}

}

}

 

11.去除ArrayList集合中的相同元素

import java.util.*;

 

class ArrayListDemo

{

public static void sop(Object obj)

{

System.out.println(obj);

}

 

public static void main(String[] args)

{

ArrayList al = new ArrayList();

al.add("java 01");

al.add("java 02");

al.add("java 01");

al.add("java 02");

al.add("java 03");

 

sop("原来" + al);

al = singleElement(al);

sop(al);

}

 

public static ArrayList singleElement(ArrayList al)

{

ArrayList newal = new ArrayList(); //创建一个新的ArrayList集合

 

Iterator it = al.iterator(); //使用迭代器遍历原集合

 

while(it.hasNext())

{

//注意在迭代循环时,next()调用一次,就需要用hasNext()判断一次

Object obj = it.next(); //使用迭代器遍历集合

 

if(!newal.contains(obj))

newal.add(obj);

}

 

return newal;

}

}

 

12.将自定义的对象存到ArrayList集合中,并去除相同元素

存人对象,同一姓名,同于元素的人视为同一个人

*/

 

import java.util.*;

 

class Person

{

private String name;

private int age;

 

//重写父类的equals方法

public boolean equals(Object obj)

{

if(!(obj instanceof Person))

return false;

 

Person p = (Person)obj; //向下转型

return (p.name.equals(this.name) && p.age == this.age);

}

 

Person(String name,int age)

{

this.name = name;

this.age = age;

}

 

public String getName()

{

return name;

}

 

public int getAge()

{

return age;

}

}

 

class ArrayListDemo

{

public static void sop(Object obj)

{

System.out.println(obj);

}

 

public static void main(String[] args)

{

ArrayList al = new ArrayList();

al.add(new Person("lisi01",35));

al.add(new Person("lisi02",32));

al.add(new Person("lisi02",32));

al.add(new Person("lisi04",39));

al.add(new Person("lisi04",39));

 

al = singleElement(al);

 

Iterator it = al.iterator();

while(it.hasNext())

{

//下面两个语句等同于 Person p = (Person)it.next();

Object obj = it.next();

Person p = (Person)obj; //向下转型

sop(p.getName() + "::" + p.getAge());

}

}

 

public static ArrayList singleElement(ArrayList al)

{

ArrayList newal = new ArrayList(); //创建一个新的ArrayList集合

 

Iterator it = al.iterator();

 

while(it.hasNext())

{

//注意在迭代循环时,next()调用一次,就需要用hasNext()判断一次

Object obj = it.next(); //使用迭代器遍历集合

 

//List集合判断元素是否相同,调用的是equals()方法

//下面调用的contains()方法底层调用的也是equals()方法

//所以需要在Person类中,重写根父类的equals()方法

if(!newal.contains(obj))

newal.add(obj);

}

 

return newal;

}

}

 

 

13. HashSet是如何保证元素的唯一性的呢?

是通过元素的两个方法,hashCode和equals来完成的

如果元素的HashCode值相同,才会判断equals是否为true

如果元素的HashCode值不同,则不会判断equals。

对于判断元素是否存在,以及删除等操作,依赖的方法是

元素的hashCode和equals方法

import java.util.*;

 

class Person

{

private String name;

private int age;

 

public int hashCode() //重写父类的哈希函数

{

return name.hashCode()+age * 37;

}

 

public boolean equals(Object obj) //重写父类的equals方法

{

if(!(obj instanceof Person))

return false;

 

Person p = (Person)obj;

return (p.name.equals(this.name) && p.age == this.age);

}

 

Person(String name,int age)

{

this.name = name;

this.age = age;

}

 

public String getName()

{

return name;

}

 

public int getAge()

{

return age;

}

}

 

class HashCodeDemo

{

public static void sop(Object obj)

{

System.out.println(obj);

}

 

public static void main(String[] args)

{

HashSet hc = new HashSet();

hc.add(new Person("lisi01",11));

hc.add(new Person("lisi02",12));

hc.add(new Person("lisi03",13));

hc.add(new Person("lisi04",14));

hc.add(new Person("lisi02",12));

 

//同样依赖hashCode和equals方法

sop(hc.remove(new Person("lisi01",11)));

 

Iterator it = hc.iterator();

while(it.hasNext())

{

Person p = (Person)it.next();

sop(p.getName() + "::" + p.getAge());

}

}

 

}

 

14.TreeSet:可以对Set集合中的元素进行排序

底层结构是二叉树

保证元素唯一性的依据:compareTo方法return 0

 

 

TreeSet排序的第一种方式:让元素自身具备比较性。

元素需要实现Comoparable接口,覆盖compareTo方法

这种方式也称为元素的自然顺序,也称为默认顺序

注意:排序时,当主要条件相同时,一定要判断下次要条件

/*

需求:根据学生的年纪进行排序,当学生的年纪相同时,根据姓名排序

*/

 

import java.util.*;

 

class Student implements Comparable

{

private String name;

private int age;

 

Student(String name,int age)

{

this.name = name;

this.age = age;

}

 

public int getAge()

{

return age;

}

 

public String getName()

{

return name;

}

public int compareTo(Object obj) //该类强制让学生具备比较性

{

if(!(obj instanceof Student))

throw new RuntimeException("比较的对象不是Student对象");

 

Student stu = (Student)obj;

if(this.age > stu.age)

return 1;

if(stu.age == this.age)

//排序时,当主要条件相同时,一定要判断下次要条件

//当年纪相同时,再根据姓名排序

return this.name.compareTo(stu.name);

return -1;

 

}

}

 

class TreeSetDemo

{

 

public static void sop(Object obj)

{

System.out.println(obj);

}

 

public static void main(String[] args)

{

TreeSet ts = new TreeSet();

 

ts.add(new Student("lisi01",20));

ts.add(new Student("lisi02",21));

ts.add(new Student("lisi02",20));

ts.add(new Student("lisi03",22));

ts.add(new Student("lisi04",23));

 

Iterator it = ts.iterator();

 

while(it.hasNext())

{

Student stu = (Student)it.next();

 

sop(stu.getName() + "::" + stu.getAge());

}

}

}

 

TreeSet的第二种排序方式

当元素自身不具备比较性时,或者具备的比较性不是所需要 的,这时就需要让集合自身具备比较性。在集合初始化时,就有了比较方式。

 

当元素自身不具备比较性,或者具备的比较性不是所需要的。这时需要让容器自身具备比较性。定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。

 

当两种排序都存在的时候,以比较器为主

定义一个类,实现Comparator接口,覆盖compare方法

 

/*

需求:根据学生的年纪进行排序,当学生的年纪相同时,根据姓名排序

*/

 

import java.util.*;

 

class Student implements Comparable

{

private String name;

private int age;

 

Student(String name,int age)

{

this.name = name;

this.age = age;

}

 

public int getAge()

{

return age;

}

 

public String getName()

{

return name;

}

 

public int compareTo(Object obj) //该类强制让学生具备比较性

{

if(!(obj instanceof Student))

throw new RuntimeException("比较的对象不是Student对象");

 

Student stu = (Student)obj;

if(this.age > stu.age)

return 1;

if(stu.age == this.age)

return this.name.compareTo(stu.name);

return -1;

}

}

 

class TreeSetDemo

{

 

public static void sop(Object obj)

{

System.out.println(obj);

}

 

public static void main(String[] args)

{

TreeSet ts = new TreeSet(new MyCompare());

 

ts.add(new Student("lisi01",20));

ts.add(new Student("lisi02",21));

ts.add(new Student("lisi09",20));

ts.add(new Student("lisi007",22));

ts.add(new Student("lisi04",23));

 

Iterator it = ts.iterator();

 

while(it.hasNext())

{

Student stu = (Student)it.next();

 

sop(stu.getName() + "::" + stu.getAge());

}

}

}

 

 

class MyCompare implements Comparator

{

//在比较器中按姓名进行排序

public int compare(Object obj1,Object obj2)

{

Student stu1 = (Student)obj1;

Student stu2 = (Student)obj2;

 

int num = stu1.getName().compareTo(stu2.getName());

if(num == 0)

{

return new Integer(stu1.getAge()).compareTo(new

Integer(stu2.getAge()));

}

return num;

}

}

 

 

练习

/*

练习:按照字符串长度排序

字符串本身具备比较性,但是它的比较方式不是所需要的

这是就使用比较器进行比较

*/

 

import java.util.*;

 

class TreeSetTest

{

public static void sop(Object obj)

{

System.out.println(obj);

}

 

public static void main(String[] args)

{

TreeSet ts = new TreeSet(new strLenCompare());

 

ts.add("abc");

ts.add("d");

ts.add("esdsdcas");

ts.add("us");

ts.add("sde");

 

Iterator it = ts.iterator();

 

while(it.hasNext())

{

sop(it.next());

}

}

}

 

class strLenCompare implements Comparator

{

public int compare(Object o1,Object o2)

{

String s1 = (String)o1;

String s2 = (String)o2;

 

//注意compareTo方法返回的正数不一定是,返回的负数不一定是-1

int num = new Integer(s1.length()).compareTo(s2.length());

 

if(num == 0)

{

//当字符串的长度相同时,按字符串的自然顺序进行排序

return s1.compareTo(s2);

}

 

return num;

}

}

你可能感兴趣的:(Java笔记--集合)