黑马程序员_JAVA_集合框架(一)

来源:互联网 发布:网络电话软件 编辑:程序博客网 时间:2024/05/16 15:34
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


一、集合框架

为什么出现集合类:

        面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。


数组和集合类同是容器,有何不同:

        数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。

数组中可以存储基本数据类型,集合只能存储对象。


集合类的特点:

        集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。

 

二、Collection接口

集合类实现的接口,该接口定义了所有集合了的共性方法。集合中存储的都是对象的引用(地址)。

Collection接口中的常见操作:

1、添加元素

         add(Objectobj); //add方法的参数类型是Object。以便于接收任意类型对象。

2、删除元素

         remove(Objectobj);

         removeAll(另一集合);//调用者只保留另一集合中没有的元素。

         clear();//清空集合

3、判断元素

        contains(Objectobj);//判断是否存在obj这个元素

        isEmpty();//是否为空

4、获取个数,集合长度

         size();

5、取交集

         retainAll(另一集合);//调用者只保留两集合的共性元素。


迭代(Iterator

迭代是取出集合中元素的一种方式。

        对于集合的元素取出这个动作:当不足以用一个函数来描述,需要用多个功能来体现,所以就将取出这个动作封装成一个对象来描述。就把取出方式定义在集合的内部,这样取出方式就可以直接访问集合内部的元素。那么取出方式就被定义成了内部类。

         这些内部类都符合一个规则(或者说都抽取出来一个规则)。该规则就是Iterator。通过一个对外提供的方法:iterator();,来获取集合的取出对象。

         因为Collection中有iterator方法,所以每一个子类集合对象都具备迭代器。

 

2、迭代的常见操作

        hasNext();//有下一个元素,返回真

        next();//取出下一个元素

        remove();//移除


3、迭代注意事项

迭代器在Collcection接口中是通用的,它替代了Vector类中的Enumeration(枚举)

迭代器的next方法是自动向下取元素,要避免出现NoSuchElementException

迭代器的next方法返回值类型是Object,所以要记得类型转换。


Collection接口常见的子接口:

List接口:元素是有序的,元素可以重复。因为该集合体系有索引。

Set接口元素是无序的,元素不可以重复。


三、List接口类

元素是有序的,元素可以重复。因为该集合体系有索引。

子类:

        ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步。

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

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


List的特有方法:

1、增加

        booleanadd(index,element);//指定位置添加元素

        BooleanaddAll(index,Collection);//在指定位置增加给定集合中的所有元素,若省略位置参数,则在当前集合的后面依次添加元素

2、删除

        Booleanremove(index);//删除指定位置的元素

3、修改

        set(index,element);//修改指定位置的元素。

4、查找

        get(index);//通过角标获取元素

        subList(from,to);//获取部分对象元素

注意:List集合判断元素是否相同,移除等操作,依据的是元素的equals方法。


ListIterator接口

List集合特有的迭代器ListIterator,是Iterator的子接口。 

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

特有方法:

       add(obj);//增加

        set(obj);//修改

        hasPrevious();//判断前面有没有元素

        previous();//取前一个元素

枚举Enumeration:

特有方法:

         addElement(obj);//添加元素

         Enumeration elements();//相当于Iterator方法

         hasMoreElements();//判断是否还有下一个元素

         nextElements();//获取下一个元素

public static void main(String[] args) {Vector v = new Vector();v.add("java01");v.add("java02");v.add("java03");Enumeration en = v.elements();while(en.hasMoreElements()){System.out.println(en.nextElement());}}


LinkedList类:

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

特有方法:

1、增加

        addFirst();// 添加元素到集合的首部

        addLast();// 添加元素到集合的尾部

2、获取

        //获取元素,但不删除元素,如果集合中没有元素,则抛出异常。

        getFirst();// 获取集合中的首元素

        getLast();// 获取集合中的为元素

3、删除

        //获取元素,并删除元素如果集合中没有元素,则抛出异常。

        removeFirst();// 删除集合中的首元素

        removeLast();// 删除集合中的尾元素

JDK1.6以后,出现了替代方法。

1、增加

        offFirst();

        offLast();

2、获取

        //获取元素,但是不删除。如果集合中没有元素,会返回null

        peekFirst();

        peekLast();

3、删除

        //获取元素,并删除元素。如果集合中没有元素,会返回null

        pollFirst();

        pollLast();

/*使用LinkedList模拟一个堆栈或者队列数据结构。堆栈:先进后出  如同一个杯子。队列:先进先出 First in First out  FIFO 如同一个水管。 */import java.util.*;class LinkedListTest {public static void main(String[] args) {LinkedList l = new LinkedList();l.addFirst("java01");l.addFirst("java02");l.addFirst("java03");l.addFirst("java04");l.addFirst("java05");// 堆栈输出// stack(l);// 队列输出queue(l);}// 堆栈public static void stack(LinkedList l) {while (!l.isEmpty()) {sop(l.removeFirst());}}// 队列public static void queue(LinkedList l) {while (!l.isEmpty()) {sop(l.removeLast());}}// 输出public static void sop(Object obj) {System.out.println(obj);}}

import java.util.ArrayList;import java.util.Iterator;//去除ArrayList集合中的重复元素class ArrayListTest {public static void sop(Object obj) {System.out.println(obj);}public static void main(String[] args) {ArrayList al = new ArrayList();// 初始化一个ArrayList对象// 添加元素al.add("java01");al.add("java02");al.add("java01");al.add("java02");al.add("java01");sop(al);// 打印原集合al = singleElement(al);sop(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;}}


四、Set集合

1、Set接口类:

元素是无序(存入和取出的顺序不一定一致),元素不可以重复。Set集合的功能和Collection是一致的。


常见的子类:     

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

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


2、HashSet类:

HashSet:底层数据结构是哈希表。是线程不安全的。不同步。

HashSet保证元素的唯一性:

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

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

3、如果元素的hashcode值不同,不会调用equals。

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

import java.util.HashSet;import java.util.Iterator;class HashSetTest {public static void sop(Object obj) {System.out.println(obj);}public static void main(String[] args) {HashSet hs = new HashSet();// 定义一个HashSet// 向这个集合中添加自定义元素hs.add(new Person("a1", 11));hs.add(new Person("a2", 12));hs.add(new Person("a3", 13));// 遍历这个集合Iterator it = hs.iterator();// 打印集合中的内容while (it.hasNext()) {Person p = (Person) it.next();sop(p.getName() + "::" + p.getAge());}}}class Person {private String name;// 人的属性private int age;Person(String name, int age) {this.name = name;this.age = age;}// 覆盖hashCode值和equals方法public int hashCode() {System.out.println(this.name + "....hashCode");return name.hashCode() + age * 37;}// 如果姓名和年龄相同就为同一个人public boolean equals(Object 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 String getName() {return name;}public int getAge() {return age;}}


3、TreeSet类:

1、底层的数据结构为二叉树结构

        2、可对Set集合中的元素进行排序,默认的排序方式是自然顺序


两种排序方式:

1、自然排序

让元素自身具备比较性。元素需要实现Comparable接口,覆盖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 String getName() {return name;}public int getAge() {return age;}// 复写hashCode以便HashSet集合调用public int hashCode() {return name.hashCode() + age;}// 复写equals以便HashSet集合和集合中一些比较方法调用public boolean equals(Object obj) {if (!(obj instanceof Student))throw new RuntimeException();Student s = (Student) obj;return this.name.equals(s.name) && this.age == s.age;}// 复写compareTo以便TreeSet集合调用public int compareTo(Object obj) {Student s = (Student) obj;if (this.age == s.age)return this.name.compareTo(s.name);return this.age - s.age;}}class TreeSetTest {public static void main(String[] args) {TreeSet<Student> t = new TreeSet<Student>();t.add(new Student("stu1", 12));t.add(new Student("stu4", 2));t.add(new Student("stu2", 12));t.add(new Student("stu3", 12));t.add(new Student("stu6", 22));for (Iterator<Student> it = t.iterator(); it.hasNext();) {Student s = it.next();System.out.println(s.getName() + "....." + s.getAge());}}}


2、比较器排序

当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性。在集合

初始化时,就有了比较方式。定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。

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

/*需求:往TreeSet集合中存储自定义对象学生。按照学生的年龄进行排序。 */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 String getName() {return name;}public int getAge() {return age;}// 复写hashCode以便HashSet集合调用public int hashCode() {return name.hashCode() + age;}// 复写equals以便HashSet集合和集合中一些比较方法调用public boolean equals(Object obj) {if (!(obj instanceof Student))throw new RuntimeException();Student s = (Student) obj;return this.name.equals(s.name) && this.age == s.age;}// 复写compareTo以便TreeSet集合调用public int compareTo(Object obj) {Student s = (Student) obj;if (this.age == s.age)return this.name.compareTo(s.name);return this.age - s.age;// return new Integer(this.age).compareTo(new Integer(s.age));}}class TreeSetTest {public static void main(String[] args) {TreeSet<Student> t = new TreeSet<Student>(new LenCompare());t.add(new Student("stu1", 12));t.add(new Student("stu4", 2));t.add(new Student("stu2", 12));t.add(new Student("stu3", 12));t.add(new Student("stu6", 22));for (Iterator<Student> it = t.iterator(); it.hasNext();) {Student s = it.next();System.out.println(s.getName() + "....." + s.getAge());}}}// 定义一个比较器,以姓名长度为主要比较class LenCompare implements Comparator<Student> {public int compare(Student s1, Student s2) {int num = new Integer(s1.getName().length()).compareTo(new Integer(s2.getName().length()));if (num == 0) {return new Integer(s1.getAge()).compareTo(s2.getAge());}return num;}}
当两种排序都存在时,以比较器为主。

0 0