黑马程序员——java基础知识之集合框架(容器)

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
1、为什么出现集合框架?
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。

2、图解集合框架的构成
这里写图片描述

3、Collection集合的主要方法
Collection定义了集合框架的共性功能。
1,添加
add(e);
addAll(collection);

2,删除
remove(e);
removeAll(collection); 删除两个集合的交集部分
clear();

3,判断。
contains(e);
isEmpty();

4,获取
iterator();
size();

5,获取交集。
retainAll(); 获取两个集合的交集部分

6,集合变数组。
toArray();

7、迭代器
迭代的常见操作
hasNext();//有下一个元素,返回真
next();//取出下一个元素

迭代器的使用方式:
使用:
ArrayList a=newArrayList();//创建一个集合
Iteratorit=a.iterator();//获取一个迭代器,用于取出集合中的元素。
第一种方式:(内存更优)
for(Iterator iter = a.iterator();iter.hasNext(); )
{
System.out.println(iter.next());
}
第二种方式:
Iteratoriter = a.iterator();
while(iter.hasNext())
{
System.out.println(iter.next());
}
注意:迭代器的next方法返回值类型是Object,所以要记得类型转换。

4、Conllectoin的子类List的集合的主要方法
List:元素是有序的,元素可以重复。因为该集合体系有索引。
特有方法。凡是可以操作角标的方法都是该体系特有的方法。


add(index,element);
addAll(index,Collection);


remove(index);


set(index,element);

get(index):
subList(from,to);
listIterator();
int indexOf(obj):获取指定元素的位置。
ListIterator listIterator();

ArrayList的一些方法应用
例子程序:

import java.util.*;
class ListDemo 
{
    public static void sop(Object obj)
    {
        System.out.println(obj);
    }
    public static void method()
    {

        ArrayList al = new ArrayList();

        //添加元素
        al.add("java01");
        al.add("java02");
        al.add("java03");

        sop("原集合是:"+al);
        //在指定位置添加元素。
        al.add(1,"java09");

        //删除指定位置的元素。
        al.remove(2);

        //修改元素。
        al.set(2,"java007");

        //通过角标获取元素。
        sop("get(1):"+al.get(1));

        sop(al);

        //获取所有元素。
        for(int x=0; x<al.size(); x++)
        {
            System.out.println("al("+x+")="+al.get(x));
        }
        //通过迭代器获取所有元素
        Iterator it = al.iterator();

        while(it.hasNext())
        {
            sop("next:"+it.next());
        }


        //通过indexOf获取对象的位置。
        sop("index="+al.indexOf("java02"));

        List sub = al.subList(1,3);

        sop("sub="+sub);
    }


    public static void main(String[] args) 
    {

        //演示列表迭代器。
        ArrayList al = new ArrayList();

        //添加元素
        al.add("java01");
        al.add("java02");
        al.add("java03");

        sop(al);

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

在迭代时,不可以通过集合对象的方法操作集合中的元素。
因为会发生ConcurrentModificationException异常。

所以,在迭代器时,只能用迭代器的放过操作元素,可是Iterator方法是有限的,
只能对元素进行判断,取出,删除的操作,
如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator。

该接口只能通过List集合的listIterator方法获取。
例子程序:

        //List的Iterator的子接口listIterator,里面提供更多迭代器操作数据的方法
        ListIterator li = al.listIterator();

        //sop("hasPrevious():"+li.hasPrevious());

        while(li.hasNext())
        {
            Object obj = li.next();
            //判断是否有java02的元素
            if(obj.equals("java02"))
                //li.add("java009");
                //通过迭代器直接操作数据
                li.set("java006");


        }
    //从后往前迭代
        while(li.hasPrevious())
        {
            sop("pre::"+li.previous());
        }
        //sop("hasNext():"+li.hasNext());
        //sop("hasPrevious():"+li.hasPrevious());
        sop(al);
        /*
        //在迭代过程中,准备添加或者删除元素。

        Iterator it = al.iterator();

        while(it.hasNext())
        {
            Object obj = it.next();

            if(obj.equals("java02"))
                //al.add("java008");
                it.remove();//将java02的引用从集合中删除了。

            sop("obj="+obj);


        }
        sop(al);

list集合的三个主要子类:
ArrayList:底层的数据结构是数组。特点:查询快,增删慢
LinkedList:底层实现是链表。 特点是:查询慢,增删快。
Vector:它的底层实现也是数组,它的版本比较老,现在基本使用ArrayList。效率低下,线程同步,被ArrayList替代了。

但是强调一个Vector的特有功能:枚举
枚举就是Vector特有的取出方式。其实枚举和迭代是一样的。
但是有IO中有用到枚举的方法。
小例子程序:

Vector v = new Vector();
Enumeration en = v.elements();

        while(en.hasMoreElements())
        {
            System.out.println(en.nextElement());
        }

Linkedlist的主要方法:
和ArrayList很多方法差不多,但是它的特有方法:
LinkedList:特有方法:
addFirst();
addLast();

getFirst();
getLast();
获取元素,但不删除元素。如果集合中没有元素,会出现NoSuchElementException

removeFirst();
removeLast();
获取元素,但是元素被删除。如果集合中没有元素,会出现NoSuchElementException

在JDK1.6出现了替代方法。
offerFirst();
offerLast();
添加元素;

peekFirst();
peekLast();
获取元素,但不删除元素。如果集合中没有元素,会返回null。

pollFirst();
pollLast();
获取元素,但是元素被删除。如果集合中没有元素,会返回null。

必须掌握的练习:
使用LinkedList模拟一个堆栈或者队列数据结构。
堆栈:先进后出 如同一个杯子。
队列:先进先出 First in First out FIFO 如同一个水管。

首先用LinkedList模仿堆栈
public class DZ{
    private LinkedList list;
    DZ(){
        list = new LinkedList();
    }

    public void myAdd(Object obj){
        list.addFirst(obj);
    }

    public Object myGet(){
        return list.removeLast()
    }

    public boolean isNull(){
        return list.isEmpty();
    }
}

class Test{
    DZ s = new DZ();
    s.myAdd("java01");
    s.myAdd("java02");
    s.myAdd("java03");
    s.myAdd("java04");
    while(!s.isNull()){
        System.out.println(s.myGet());
    }
}
//如果要模仿队列先进后出,就修改一下myGet()方法;
//改为return list.removeFirst();

新程序的例子:

package cn.dhjJH;

import java.util.*;

/*
 * 需求:去除ArrayList里面的重复元素
 */
public class Test01 {
    public static void main(String[] args){
    //定义一个ArrayList容器,往里面添加元素
    ArrayList al = new ArrayList();
    al.add("java01");
    al.add("java02");
    al.add("java01");
    al.add("java02");
    al.add("java03");
    sop(al);
    sop(singLink(al));

    }
    //定义去除容器重复元素的方法
    public static List singLink(ArrayList al){
        ArrayList newAl = new ArrayList();
        //通过迭代器,将原容器的元素获取
        Iterator s = al.iterator();
        while(s.hasNext()){
            Object obj = s.next();
            //判断显得容器里面是否含有原容器的元素,保证新容器里面的元素是原容器里面没有重复的元素
            if(!newAl.contains(obj)){
                newAl.add(obj);
            }
        }
        return newAl;
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }

}

ArrayList练习二:

package cn.dhjJH;

import java.util.*;

/*
 * 往ArrayList里面存储对象,比如:存人对象。同姓名同年龄,视为同一个人。为重复元素。
 * 思路:对人进行描述,将数据封装到对象
 * 定义容器,将数据存入
 * 从容器中将数据取出
 * 
 * 总结:List中的remove方法和contains方法底层都是调用的equals方法
 */
public class Test02 {
    public static void main(String[] args){
    //存储对象元素
    ArrayList al = new ArrayList();
    al.add(new person("zhangsan",20));
    al.add(new person("lisi",22));
    al.add(new person("wangwu",23));
    al.add(new person("xiaoliu",21));
    al.add(new person("xiaoliu",21));
    al=getSingle(al);

    //通过迭代器取出容器中的元素
    Iterator s = al.iterator();
    while(s.hasNext()){
        person p = (person)s.next();
        sop(p.getName()+"..."+p.getAge());
    }
    }

    //定义一个去除重复对象元素的方法
    public static ArrayList getSingle(ArrayList al){
        ArrayList nl = new ArrayList();
        Iterator it = al.iterator();
        while(it.hasNext()){
            Object obj = it.next();
            if(!nl.contains(obj)){
                nl.add(obj);
            }
        }
        return nl;
    }

    public static void sop(Object obj){
        System.out.println(obj);
    }
}
//将Person数据封装成对象
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 int getAge(){
        return age;
    }
    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;
    }
}

5、Collection的另一个子类set的容器
Set:元素是无序(存入和取出的顺序不一定一致),元素不可以重复。、

①HashSet:底层数据结构是哈希表。是线程不安全的。不同步。
HashSet是如何保证元素唯一性的呢?
是通过元素的两个方法,hashCode和equals来完成。
如果元素的HashCode值相同,才会判断equals是否为true。
如果元素的hashcode值不同,不会调用equals。

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

例子程序:
往HashSet中添加自定义元素

package cn.dhjJH;

import java.util.*;

public class Test03 {
    public static void main(String[] args){
        HashSet hs = new HashSet();
        hs.add(new person1("a1",22));
        hs.add(new person1("a2",22));
        hs.add(new person1("a3",24));
        hs.add(new person1("a1",22));
        //用迭代器打印输出元素
        Iterator it = hs.iterator();
        while(it.hasNext()){
            person1 p = (person1)it.next();
            sop(p.getName()+"..."+p.getAge());
        }
    }
    public static void sop(Object obj){
        System.out.println(obj);
    }
}

//自定义person类,并复写hashcode和equals方法
class person1{
    private String name;
    private int age;
    public person1(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    public String getName(){
        return name;
    }
    public int getAge(){
        return age;
    }
    //重写hashcode和equals方法
    public int hashCode(){
        return name.hashCode()+age*39;
    }
    public boolean equals(Object obj){
        if(!(obj instanceof person1)){
            return false;
        }
        person1 p = (person1)obj;
        return this.name.equals(p.name)&&this.age==p.age;
    }
}

对于判断元素是否存在contains(),以及删除remove()等操作,依赖的方法是元素的hashcode和equals方法.先判断hashcode,再判断equals()方法。List中只是依靠equals()方法。

②TreeSet容器:
可以对Set集合中的元素进行排序。
底层数据结构是二叉树。
保证元素唯一性的依据:
compareTo方法return 0.

TreeSet排序的第一种方式:让元素自身具备比较性。
元素需要实现Comparable接口,覆盖compareTo方法。
也种方式也成为元素的自然顺序,或者叫做默认顺序。

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

例子程序:

/*需求:
往TreeSet集合中存储自定义对象学生。
想按照学生的年龄进行排序。

记住:排序时,当主要条件相同时,一定判断一下次要条件。
*/
class TreeSetDemo 
{
    public static void main(String[] args) 
    {
        TreeSet ts = new TreeSet();

        ts.add(new Student("lisi02",22));
        ts.add(new Student("lisi007",20));
        ts.add(new Student("lisi09",19));
        ts.add(new Student("lisi08",19));
        //ts.add(new Student("lisi007",20));
        //ts.add(new Student("lisi01",40));

        Iterator it = ts.iterator();
        while(it.hasNext())
        {
            Student stu = (Student)it.next();
            System.out.println(stu.getName()+"..."+stu.getAge());
        }
    }
}


class Student implements Comparable//该接口强制让学生具备比较性。
{
    private String name;
    private int age;

    Student(String name,int age)
    {
        this.name = name;
        this.age = age;
    }
//重写compareTo方法
    public int compareTo(Object obj)
    {
        if(!(obj instanceof Student))
            throw new RuntimeException("不是学生对象");
        Student s = (Student)obj;

        System.out.println(this.name+"....compareto....."+s.name);
        if(this.age>s.age)
            return 1;
        if(this.age==s.age)
        {
            //比较次要条件
            return this.name.compareTo(s.name);
        }
        return -1;
    }

    public String getName()
    {
        return name;

    }
    public int getAge()
    {
        return age;
    }
}

TreeSet的底层数据结构:二叉树
可以对Set集合中的元素进行排序。
底层数据结构是二叉树。
保证元素唯一性的依据:
compareTo方法return 0.
如图说明:
这里写图片描述

TreeSet排序的第二种方式:
实现Comparator接口,覆盖compare方法。

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

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

通过例子程序说明:

package cn.dhjJH;

import java.util.*;

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

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

定义一个类,实现Comparator接口,覆盖compare方法。
 */
 //定义了两种比较的方式
public class Test04 {
    public static void main(String[] args){
    //调用第一种比较方式,实现Comparable接口,重写compareTo方法
    //TreeSet s = new TreeSet();
    //调用第二种比较方式,使用比较器,通过实现Comparator接口,重写compare方法
    TreeSet s = new TreeSet(new MyCompare());
    s.add(new Student("a1",22));
    s.add(new Student("a2",20));
    s.add(new Student("a3",23));
    s.add(new Student("a5",22));
    s.add(new Student("a2",20));
    Iterator it = s.iterator();
    while(it.hasNext()){
        Student st = (Student)it.next();
        System.out.println(st.getName()+"..."+st.getAge());
    }
}
}
//第一种比较方式,是通过使容器里面的元素具有比较性,是通过age比较
class Student implements Comparable{
    private String name;
    private 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;
    }
//定义第二种比较方式,比较器,通过比较器使容器具有比较性。
    public int compareTo(Object obj){
        if(!(obj instanceof Student))
            System.out.println("不是学生,比个毛线");
        Student stu = (Student)obj;
        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 new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
        }
        return num;
    }
}

小练习题:

package cn.dhjJH;

import java.util.*;

/*
 * 往容器中添加字符串,并按照字符串的长度排序
 */
public class Test5 {
    public static void main (String[] args){
        TreeSet ts = new TreeSet(new MyCompare1());
        ts.add("abc");
        ts.add("aaadddd");
        ts.add("abcdd");
        ts.add("abcef");
        ts.add("aaa");
        Iterator it = ts.iterator();
        while(it.hasNext()){
            Object obj = it.next();
            System.out.println(obj);
        }
    }

}
//通过比较器,定义通过字符串长度来排序
//细线Comparator接口,重写compare方法
class MyCompare1 implements Comparator{
    public int compare(Object o1,Object o2){
        String s1 = (String) o1;
        String s2 = (String) o2;
        //整数对象调用它本身的compareTo方法比较
        int num =new Integer(s1.length()).compareTo(new Integer(s2.length()));
        if(num==0){
            return s1.compareTo(s2);
        }
        return num;

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值