Java学习笔记(集合_1)

16 集合

16.2 集合类

为何出现集合类:
为方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。

集合类与数组的区别:

  1. 数组的长度是固定的,集合可以动态扩展;
  2. 数组只能通过数组下标访问元素,类型固定,而有的集合可以通过任意类型查找所映射的具体对象;

    import java.util.ArrayList;
    
    public class CollectionDemo {
        public static void main(String[] args) {
            ArrayList a = new ArrayList();
    
            a.add("java1");
            a.add("java2");
            a.add("java3");
            a.add("java4");
    
            ArrayList b = new ArrayList();
            b.add("java1");
            b.add("java2");
            b.add("java6");
            b.add("java9");
    
            a.retainAll(b);
            write("a:"+a);
            write("b:"+b);
            base_method();
        }
    
        public static void base_method(){
            //创建一个集合容器,使用Collection接口的子类ArrayList
            ArrayList a1 = new ArrayList();
            //添加元素
            a1.add("java1");
            a1.add("java2");
            a1.add("java3");
            a1.add("java4");
            write(a1);
            //删除元素
            a1.remove("java2");
    
            write(a1);
    
            write("java4是否存在:"+a1.contains("java4"));
            write("集合是否为空:"+a1.isEmpty());
        }
        public static void write(Object obj){
            System.out.println(obj);
        }
    }
    

    运行结果:

集合的作用:

a、在类的内部,对数据进行组织;
b、简单而快速的搜索大数量的条目;
c、有的集合接口,提供了一系列排列有序的元素,并且可以在序列中间快速的插入或者删除有关元素;
d、有的集合接口,提供了映射关系,可以通过关键字(key)去快速查找到对应的唯一对象,而这个关键字可以是任意的。

Java集合框架:Collection、Map

16.2.1 Collection接口

Collection类

  • List:元素是有序的,元素可以重复,因为该集合体系有索引;
  • Set:元素是无序,元素不可以重复。

a)是List、Set和Queue接口的父接口

b)定义了可用于操作List、Set和Queue的方法–增删改查

16.2.1.1 ArrayList

List:特有的常见方法。
有一个共性特点就是都可以操作角标。

  1. List接口及其实现类—ArrayList

    a)List是元素有序并且可以重复的集合,被称为序列;

    b)List可以精确的控制每个元素的插入位置,或删除某个位置元素;

    c)ArrayList——数组序列,是List的一个重要实现类;

    d)ArrayList底层是由数组实现的。

    特点:查询速度快,但是增删稍慢。

  2. List接口及其实现类—LinkedList

    特点:增删速度很快,查询速度稍慢.

  3. List接口及其实现类—Vector

    底层是数组数据接口/线程同步,被ArrayList替代了.

例1:

import java.util.ArrayList;
import java.util.Iterator;

public class ListDemo {

    public static void main(String[] args) {
        ArrayList a1 = new ArrayList();

        a1.add("java1");
        a1.add("java2");
        a1.add("java3");

        Iterator it = a1.iterator();
        while(it.hasNext()){
            Object obj = it.next();
            if(obj.equals("java2"))
                a1.add("java4");//不能通过集合对象方法操作元素

            write("obj="+obj);

        }
        write("a1="+a1);
    }

    public static void write(Object obj){
        System.out.println(obj);
    }
}

运行结果:

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

在迭代时,不可通过集合对象的方法操作集合中的元素,因为会发生ConcurrentModificationException异常,如上例;所以,在迭代器中,只能用迭代器方法操作元素,但是Interator方法时有限的,只能对元素进行判断(hasNext()),删除(remove())和取出(next())操作,如果需要进行其他操作,则需要使用其子接口ListIterator。该接口只能通过List集合的ListInterator获取。如例2、例3。

例2:

import java.util.ArrayList;
import java.util.ListIterator;

public class ListDemo {

    public static void main(String[] args) {
        ArrayList a1 = new ArrayList();

        a1.add("java1");
        a1.add("java2");
        a1.add("java3");

        ListIterator it = a1.listIterator();
        while(it.hasNext()){
            Object obj = it.next();
            if(obj.equals("java2"))
                it.add("java4");

            write("obj="+obj);

        }
        write("a1="+a1);
    }

    public static void write(Object obj){
        System.out.println(obj);
    }
}

例3:

import java.util.ArrayList;
import java.util.ListIterator;

public class ListDemo {

    public static void main(String[] args) {
        ArrayList a1 = new ArrayList();

        a1.add("java1");
        a1.add("java2");
        a1.add("java3");

        ListIterator it = a1.listIterator();
        write("hasPrevous="+it.hasPrevious());
        while(it.hasNext()){
            Object obj = it.next();
            if(obj.equals("java2")){
                //it.add("java4");
                it.set("javab");
            }       
        }
        write("hasPrevous="+it.hasPrevious());
        write("hasNext="+it.hasNext());
        while(it.hasPrevious()){
            it.previous();  
        }
        write("a1="+a1);
    }

    public static void write(Object obj){
        System.out.println(obj);
    }
}

例4

import java.util.ArrayList;
import java.util.Iterator;

public class ArrayListTest {

    public static void main(String[] args) {
        ArrayList a1 = new ArrayList();

        a1.add(new Person("zhangsan",31));
        a1.add(new Person("lisi",32));
        a1.add(new Person("wangwu",33));
        a1.add(new Person("zhaoliu",34));
        a1.add(new Person("wangwu",33));

    /*  Iterator it = a1.iterator();
        while(it.hasNext()){
            Person p = (Person)it.next();
            write(p.getName()+":"+p.getAge());
        }*/
        a1  = singleElement(a1);
        Iterator it1 = a1.iterator();
        while(it1.hasNext()){
            Person p1 = (Person)it1.next();
            write(p1.getName()+":"+p1.getAge());
        }
    }

    public static ArrayList singleElement(ArrayList a1){
        ArrayList newA1 = new ArrayList();

        Iterator it = a1.iterator();
        while(it.hasNext()){
            Object obj=it.next();
            if(!newA1.contains(obj))
                newA1.add(obj);
            }
        return newA1;
        }

    public static void write(Object obj){
        System.out.println(obj);
    }
}

class Person{
    private String name;
    private int age;
    Person(String name,int age){
        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;
    }
}

运行结果:

16.2.1.2 Vector

枚举是Vector特有的取出方式,枚举和迭代是一样的。

因为枚举的名称以及方法的名称都过长,所以被迭代器取代了.

例5

import java.util.Enumeration;
import java.util.Vector;

public class VectorDemo {

    public static void main(String[] args) {
        Vector v = new Vector();
        v.add("java1");
        v.add("java2");
        v.add("java3");

        Enumeration en = v.elements();
        while(en.hasMoreElements()){
            System.out.print(en.nextElement());
        }
    }
}

运行结果:java1java2java3

16.2.1.3 LinkedList

LinkedList方法:
addFirst();
addLast();

16.2.1.4 HashSet

Set:元素不可以重复,是无序。
Set接口中的方法和Collection一致。

|–HashSet:内部数据结构是哈希表,是不同步的。

|–TreeSet:可以对Set集合中的元素进行排序,是不同步的。

哈希表确定元素是否相同

  1. 判断的是两个元素的哈希值是否相同。
    如果相同,再判断两个对象的内容是否相同。
  2. 判断哈希值相同,其实判断的是对象的HashCode方法。判断内容相同,用的是equals方法。
  3. 如果哈希值不同,不需要判断equals。

例6:

import java.util.HashSet;
import java.util.Iterator;

public class HashSetDemo {
    public static void main(String[] args) {
        HashSet hs = new HashSet();

        hs.add(new Person("a1",13));
        hs.add(new Person("a1",13));
        hs.add(new Person("a2",14));    
        hs.add(new Person("a3",11));

        write(hs.contains(new Person("a2",14)));
        hs.remove(new Person("a1",13));
        Iterator it = hs.iterator();
        while(it.hasNext()){
            Person p= (Person)it.next();
            write(p.getName()+":"+p.getAge());
        }
    }

    public static void write(Object obj){
        System.out.println(obj);
    }
}

class Person{
    private String name;
    private int age;
    Person(String name,int age){
        this.name=name;
        this.age=age;
    }
    public String getName(){
        return name;
    }
    public int getAge(){
        return age;
    }
    public int hashCode(){
        System.out.println(this.name+"..hashcode");
        return name.hashCode()+age;
    }
    public boolean equals(Object obj){
        if(!(obj instanceof Person))
            return false;
        Person p = (Person)obj;
        System.out.println(this.name+"..equals"+this.age);
        return this.name.equals(p.name) && this.age == p.age;
    }
}

运行结果:

Ps:

  1. 一般使用HashSet会重写HashCode和equals。
  2. 对于判断元素是否存在(contains),以及删除(remove)等操作,依赖的方法是元素的hashCode和equals方法。
16.2.1.5 TreeSet

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

例7:

import java.util.Iterator;
import java.util.TreeSet;

public class TreeSetDemo {

    public static void main(String[] args) {
        TreeSet ts = new TreeSet();
        ts.add(new Student("Lili",13));
        ts.add(new Student("Lily",19));
        ts.add(new Student("Mick",15));
        ts.add(new Student("Black",15));
        ts.add(new Student("Black",11));

        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;

    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }

    Student(String name,int age){
        this.name = name;
        this.age = age;
    }
    public int compareTo(Object obj){
        if(!(obj instanceof Student))
            throw new RuntimeException("不是学生对象");
        Student s = (Student)obj;
        System.out.println(this.name+"..equals.."+this.age);
        if(this.age>s.age)
            return 1;
        else if(this.age<s.age)
            return -1;
        else 
            return (this.name.compareTo(s.name));   
    }
}

运行j结果:

排序时,当主要条件相同时,必须判断次要条件。

TreeSet底层数据时二叉树,保证元素唯一性的语句,应用compareTo方法return 0;

  • TreeSet对元素进行排序的方式一:
    让元素自身具备比较功能,元素就需要实现Comparable接口,覆盖compareTo方法。如例7.

  • TreeSet对元素进行排序的方式二:
    让元素自身不具备比较功能,或者具备的比较性不是所需要的,这时让集合自身初始化时具备比较功能,定义一个类实现Comparator接口,覆盖compare方法。将该类对象作为参数传递给TreeSet集合的构造函数。如例8。方式二更具有实用性。

例8:

    import java.util.Comparator;
    import java.util.Iterator;
    import java.util.TreeSet;

    public class TreeSetDemo2 {
        public static void main(String[] args) {
            TreeSet ts = new TreeSet(new MyCompre());
            ts.add(new Student1("Lili",13));
            ts.add(new Student1("Lily",19));
            ts.add(new Student1("Mick",15));
            ts.add(new Student1("Black",15));
            ts.add(new Student1("Black",11));

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

    class MyCompre implements Comparator{
        public int compare(Object o1, Object o2) {
            Student1 s1 = (Student1)o1;
            Student1 s2 = (Student1)o2;

            int num = s1.getName().compareTo(s2.getName());
            if(num==0)
                return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
            return num;
        }
    }

    class Student1 {
        private String name;
        private int age;

        public String getName() {
            return name;
        }
        public int getAge() {
            return age;
        } 

        Student1(String name,int age){
            this.name = name;
            this.age = age;
        }
        public int compareTo(Object obj){
            if(!(obj instanceof Student1))
                throw new RuntimeException("不是学生对象");
            Student1 s = (Student1)obj;
            System.out.println(this.name+"..equals.."+this.age);
            if(this.age>s.age)
                return 1;
            else if(this.age<s.age)
                return -1;
            else 
                return (this.name.compareTo(s.name));   
        }
    }

运行结果:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值