黑马程序员——java基础——集合(一)

来源:互联网 发布:2015年度十大网络剧 编辑:程序博客网 时间:2024/04/30 08:49

——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

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

数组虽然也可以存储对象,但数组的长度是固定的,集合的长度是可变的
数组中可以存储基本数据类型,集合中只能存储对象

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

List集合和Set集合
List 集合元素是有序的,可以重复,因为该集合有索引
ArrayList 底层结构是数组结构,特点查询快,增删较慢,线程不同步
LinkedList 底层结构是链表结构,特点 增删快,查询较慢
Vector 底层结构是数组结构,它是线程同步的,被ArrayList替代了

Set集合 元素是无序的,不可以重复
HashSet 底层结构是哈希表
其保证元素唯一性的原理:
在存入时首先是比较各元素的哈希值,若哈希值相同再调用equals方法,在添加元素时,会调用元素的hashCode方法和equals方法
注意:HashSet集合中删除,判断元素是否存在等方法依赖的方法是hashCode和equals方法
元素在HashSet集合中是没有顺序的,或者说是按照其特定的哈希值排序
TreeSet 底层结构是二叉树
TreeSet集合可以对集合中的元素进行排序
TreeSet集合在添加一个对象时,对象必须具备比较性
TreeSet集合保证元素唯一性的原理:在添加时他会调用所添加元素的compareTo方法
通过返回的值对元素进行排序,若返回0,则认为这两个元素是一样的
该集合对元素进行排序的另一种方法是:自定义一个比较器,并将这个比较器作为参数传给该集合的构造函数,实现comparator接口,复写该接口中的compare方法

集合中的较为常用的共性方法:boolean add(E e) 确保此 collection 包含指定的元素(可选操作)。 boolean addAll(Collection<? extends E> c) 将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。 void clear() 移除此 collection 中的所有元素(可选操作)。 boolean contains(Object o) 如果此 collection 包含指定的元素,则返回 trueboolean containsAll(Collection<?> c) 如果此 collection 包含指定 collection 中的所有元素,则返回 trueboolean equals(Object o) 比较此 collection 与指定对象是否相等。 int hashCode() 返回此 collection 的哈希码值。 boolean isEmpty() 如果此 collection 不包含元素,则返回 true。 Iterator<E> iterator() 返回在此 collection 的元素上进行迭代的迭代器。 boolean remove(Object o) 从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。 boolean removeAll(Collection<?> c) 移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。 boolean retainAll(Collection<?> c) 仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)。 int size() 返回此 collection 中的元素数。 Object[] toArray() 返回包含此 collection 中所有元素的数组。        

对于不同的集合它还具有一些自己特定的方法,如List集合可以通过角标对元素进行操作等,对于一些特定的方法,我们可以通过查阅API文档来学习。

迭代器是集合中取出元素的一种非常重要的方法

List集合:取出集合中的元素

import java.util.*;class ListDemo{    public static void main(String[] args)     {        ArrayList a = new ArrayList();        a.add("a");        a.add("b");        a.add("c");        a.add("d");        System.out.println(a);        /*        在取出集合中的元素时,在取出的过程中对集合中的元素进行操作        注意:在使用迭代器的方法取出集合中的元素时,        不能使用集合中的方法在取出的过程中对元素进行操作,        否则会发生 ConcurrentModificationException,并发修改异常        list 集合有其特殊的迭代器方法ListIterator,可以在取出的过程中对元素进行操作        因为该集合每个元素有对应的角标        */          ListIterator li = a.listIterator();        while(li.hasNext())        {            Object obj = li.next();            if (obj.equals("b"))            {                li.set("f");            }            System.out.println(obj);//obj不会随着对元素的不同操作而改变,它在元素改变之前就已经指向了该元素        }        System.out.println(a);        //逆向遍历集合并取出集合中的元素,这是List集合才具备的方法        while (li.hasPrevious())        {            System.out.println(li.previous());        }    }}

总结:迭代器是取出集合中元素常用的方法,在取出元素的过程中一般不能对元素进行操作,但对于List集合而言,由于其具有角标的特性,所以在元素的取出过程中,它具备一些特定的对元素进行操作的方法。

用LinkedList模拟队列和堆栈数据结构
队列:先进先出
堆栈:先进后出
思路:
自定义一个类(基于LinkedList),对外提供添加和取出的方法

import java.util.*;class DuiLie{    private LinkedList link ;//将link定义在成员位置上,这样每个方法就可以使用这个对象    DuiLie()    {        link = new LinkedList();    }    public void Myadd(Object obj)    {        link.addLast(obj);    }    public Object Myget()    {        //因为获取元素后,那个元素就需要清除,所以这里用remove() 而不用get()        return link.removeFirst();    }    public boolean isNull()    {        return link.isEmpty();    }}class LinkedListTest {    public static void main(String[] args)     {        DuiLie d = new DuiLie();        d.Myadd("a");        d.Myadd("b");        d.Myadd("c");        while(!d.isNull())        {            System.out.println(d.Myget());        }    }}

总结:由于LinkedList集合它具有对第一个元素和最后一个元素进行操作的方法
通过这几个方法我们可以很好的模拟出队列和堆栈数据结构

需求:将自定义的人对象添加到List集合中,并去除相同的元素
规定同姓名和同年龄为相同的人
思路:
1.先描述人
2.定义方法可以获取人的姓名和年龄
3.复写父类的equals方法,自定义比较的方法
4.提供一个去除相同元素的方法,在迭代的过程中将比较每个人,并将相同的对象去掉
5.打印集合中的元素

import java.util.*;class Person{       private String name;    private int age ;    Person(String name,int age)    {        this.name = name;        this.age = age;    }    //覆盖父类中的equals方法,让其按照自定义的方法进行比较    public boolean equals(Object obj)    {        if(!(obj instanceof Person))            throw new RuntimeException("类型转换异常");        Person p = (Person)obj;        return this.name.equals(p.name) && this.age == p.age;    }    public String getName()    {        return name;    }    public int getAge()    {        return age;    }}class ArrayListTest{    public static void main(String[] args)     {        ArrayList a = new ArrayList();        a.add(new Person("zhangsan",21));        a.add(new Person("zhangsan",22));        a.add(new Person("zhangsan",22));        a.add(new Person("zhangsan",24));        a.add(new Person("zhangsan",23));        a.add(new Person("zhangsan",23));        a = singleList(a);        Iterator it = a.iterator();        while(it.hasNext())        {            Person p = (Person)it.next();//it.next()返回的是Object,父类Object中没有getName和getAge等方法,所以需要强转            System.out.println(p.getName()+"...."+p.getAge());        }    }    /*    去除集合中重复的元素    思路:    1.定义一个新的集合    2.在用迭代器取出原集合中的对象时,判断新的集合中有没有那个对象,    如果有则不添加,如果没有则添加    3.将这个新的集合返回    */    public static ArrayList singleList(ArrayList a)    {        ArrayList a1 = new ArrayList();        Iterator it = a.iterator();        while(it.hasNext())        {            Object obj = it.next();            if(!a1.contains(obj))            /*contains底层调用的是equals方法,所以当传入的对象是自定义时,需要自定义一个equals方法,让其按照自定义的方法进行比较            List 集合中的很多方法底层调用的都是equals方法            */                a1.add(obj);        }        return a1;    }}

Set集合:
Set集合是无序的且元素不可以重复
需求:往HashSet集合中存入自定义对象,并保证对象的唯一性
HashSet 集合保证元素唯一性的原理
在存入元素时首先是比较各个元素的哈希值,在哈希值相同的情况下再调用equals方法
所以在描述对象时必须覆盖父类的hashCode()和equals();

class Person{    private String name;    private int age;    Person(String name, int age)    {        this.name = name;        this.age = age;    }    //覆盖父类的hashCode()方法    public int hashCode()    {        System.out.println(this.name+".....hashCode.....");        return name.hashCode()+age*12;    }    //覆盖父类的equals()方法    public boolean equals(Object obj)    {        if(!(obj instanceof Person))            throw new RuntimeException("类型转换异常");        Person p = (Person)obj;        System.out.println(this.name+"..比较.."+p.name);        return this.name.equals(p.name) && this.age == age ;    }    public String getName()    {        return name;    }    public int getAge()    {        return age;    }}

TreeSet集合,可以对元素进行排序,首先对象一定要具备可比较性,可以通过实现Comparable接口让类强制具备比较性,如果默认的排序方式不是所想要的,可以自定义一个比较器,并将这个比较器作为参数传给该集合的构造函数
需求:
将传入的人对象按照年龄排序
自定义一个比较器,让人按照姓名排序

import java.util.*;class TreeSetDemo {    public static void main(String[] args)     {        //如果通过构造函数传入比较器,会按照比较器进行排序        TreeSet ts = new TreeSet(new MyCom());        ts.add(new Person("a",35));        ts.add(new Person("d",18));        ts.add(new Person("a",22));        ts.add(new Person("bb",24));        Iterator it = ts.iterator();        while (it.hasNext())        {            Person p = (Person)it.next();            System.out.println(p.getName()+"...."+p.getAge());        }    }}class Person implements Comparable{    private String name ;    private int age;    Person(String name,int age)    {        this.name = name;        this.age = age;    }    //实现Comparable接口,复写父类的compareTo方法,使其按照自定义的方法排序    public int compareTo(Object obj)    {        if (!(obj instanceof Person))            throw new RuntimeException("不是人对象");        Person p = (Person)obj;    System.out.println(this.name+".....compareTo......."+p.name);        //基本数据类型不能调用compareTo方法,所以要将其包装成对象        int num = new Integer(this.age).compareTo(new Integer(p.age));        if (num==0)            return this.name.compareTo(p.name);        return num;    }    //有可能用到的是hashSet集合,所以要覆盖父类的hashCode()方法    public int hashCode()    {        return this.name.hashCode()+age*12;    }    public boolean equals(Object obj)    {        if(!(obj instanceof Person))            throw new RuntimeException("不是人对象");        Person p = (Person)obj;        return this.name.equals(p.name) && this.age==p.age;    }    public String getName()    {        return name;    }    public int getAge()    {        return age;    }}//自定义一个比较器,实现Comparator接口并覆盖其compare方法,可以自定义一个排序方式class MyCom implements Comparator {    public int compare(Object o1,Object o2)    {        Person p1 = (Person)o1;        Person p2 = (Person)o2;        //先比较姓名,在姓名相同的情况下在比较年龄        int num = p1.getName().compareTo(p2.getName());        if(num==0)            return new Integer(p1.getAge()).compareTo(new Integer(p2.getAge()));        return num;    }}

总结:当对象有序并且可以重复我们可以将对象存入到List集合中
当对象无序并且不可以重复是我们可以将对象存入到Set集合中,
在选择Set集合时,如果需要对其进行排序,我们可以将其存入到TreeSet集合中

0 0
原创粉丝点击