JavaSE-集合

什么是集合?

概念:

对象的容器,定义了对多个对象进行操作的常用方法,可以实现数组功能。

和数组的区别?

(1)数组长度固定,集合长度不固定

(2)数组可以存储基本类型和引用类型,集合只能存储引用类型

Collection体系?

Collection:List+Set

List:ArrayList+LinkedList+Vector

Set:HashSet+TreeSet(实现自SortedSet接口)

//Collection,List,Set,SortedSet都是接口

个人理解:

Java的集合都是由三个接口派生而出的,即Collection,Map,Iterator
为什么List接口和Set接口要继承自Collection呢?
    假如想要造车你会去定义一些抽象方法,然后再往下细分,你可能会造汽车,卡车,汽车和卡车都是车,它俩共同的特点
    就可以继承自父类车,所以Collection内的东西是List和Set共性的东西
    接口(里面只放抽象方法,用来定义规范)
    |
    抽象类(里面一方面继承了接口的方法,一方面可以自己实现一部分通用方法,还有一部分抽象方法)
    |
    普通类(也叫实现类,用来实现前面接口和抽象类中的抽象方法,是要具体实现功能的)

对Collection接口的介绍?

Collection接口?

某些方法:

removeAll方法:如集合A有1234,集合B有12,则A.removeAll(B),A就剩下34了。即A-B

retainAll方法:取两个集合的交集,即A∩B

collection接口的操作:

Collection collection = new ArrayList();
        //1.增加操作
        collection.add("地瓜");
        collection.add("葡萄糖");
        collection.add("西瓜汁");
        //System.out.println(collection.size());//输出3
        //2.删除操作
        collection.remove("地瓜");
        System.out.println(collection.size());//输出2,删除了地瓜
        collection.clear();
        System.out.println(collection.size());//输出0,将集合的元素清空
        //3.遍历(重点)
        //3.1增加for,collection集合不能使用for,因为没有下标
        for(Object o : collection){
            System.out.println(o);//输出地瓜,葡糖糖,西瓜汁
        }
        //3.2使用迭代器,专门用来遍历集合的一种方法
        Iterator iterator = collection.iterator();
        /*
        查找API,Iterator接口有三个方法
        hasNext():如果仍有元素可以迭代,则返回true,即有没有下一个元素
        next():返回迭代的下一个元素,即获取下一个元素
        remove:从迭代器指向的collection中移除迭代器返回的最后一个元素,即删除当前元素
         */
        System.out.println("迭代器遍历:");
        while(iterator.hasNext()){
            String s = (String) iterator.next();
            System.out.println(s);
            //collection.remove(s);//在迭代的过程中,不能使用collection的方法去删除元素,只能用iterator中的删除方式
            //iterator.remove();
            System.out.println(collection.size());
        }
        //4.判断
        System.out.println(collection.contains("西瓜"));
        System.out.println(collection.isEmpty());//判断是否为空
  Collection collection = new ArrayList();
        //添加数据
        Students s1 = new Students("张三",18);
        Students s2 = new Students("李四",19);
        Students s3 = new Students("王二麻子",20);
        collection.add(s1);
        collection.add(s2);
        collection.add(s3);
        //System.out.println(collection.size());
        //System.out.println(collection.toString());
        //删除
        //collection.remove(s1);
        //collection.clear();//将三个对象在集合中清除,但这个三个对象还存在,因为在假如集合时,只是把地址加进集合了
        //遍历
        //增加for
        System.out.println("增强for:");
        for(Object o:collection){
            System.out.println(o);
        }
        //迭代器
        System.out.println("迭代器:");
        Iterator it = collection.iterator();
        while(it.hasNext()){
            Students s = (Students)it.next();
            System.out.println(s);
        }
        //判断
        System.out.println(collection.contains(s1));
        System.out.println(collection.isEmpty());
    }

List接口?

特点:有序,顺序时添加时的顺序,有下标(遍历时可以用下标来操作,插入时可以插入到指定位置,可以通过下标获取元素),元素可重复

List实现类

ArrayList:数组结构实现,查询快,增删慢,运行效率快,线程不安全

LinkedList:双向链表结构实现,增删快,查询慢

Vector:数组结构实现,查询快,增删慢,运行效率慢,线程安全

ArrayList和LinkedList区别:

1.ArrayList必须开辟连续空间,查询快,增删慢,LinkedList无需开辟连续空间,查询慢,增删快

对List接口的操作:

 List list = new ArrayList();
        //1.添加
        list.add("香蕉船");
        list.add(0,"臭番薯");
        list.add(0,"烂鸟蛋");
        System.out.println(list);//[烂鸟蛋, 臭番薯, 香蕉船]
        //2.删除
        list.remove("香蕉船");
        list.remove(0);
        //System.out.println(list);//[臭番薯]
        //3.遍历
        //3.1增强for
        System.out.println("增强for:");
        for(Object o : list){
            System.out.println(o);
        }
        //3.2迭代器
        System.out.println("迭代器:");
        Iterator it = list.iterator();
        while(it.hasNext()){
            String s = (String) it.next();
            System.out.println(s);
        }
        //3.3使用for
        System.out.println("普通for:");
        for(int i = 0;i<list.size();i++){
            System.out.println(list.get(i));
        }
        //3.4列表迭代器
        //ListIterator可以向前向后遍历,添加,删除,修改元素
        System.out.println("列表迭代器:");
        System.out.println("从前往后:");
        ListIterator listIterator = list.listIterator();
        while(listIterator.hasNext()){
            System.out.println(listIterator.nextIndex()+" "+listIterator.next());//打印下个元素下标和下个元素
        }
        System.out.println("从后往前:");
        //默认情况下,指针是第一个元素之前,要先遍历到最后,才能再往前遍历
        while(listIterator.hasPrevious()){
            System.out.println(listIterator.previousIndex()+" "+listIterator.previous());
        }
        //4.判断
        System.out.println(list.contains("香蕉船"));
        System.out.println(list.isEmpty());
        //5.获取位置
        System.out.println(list.indexOf("香蕉船"));
    }

代码简述:实现List接口的实现类ArrayList,LinkedList,Vector的遍历方式有普通for循环,增强for循环,普通迭代器和列表迭代器。 

ArrayList的底层结构和源码分析

先说结论

1.ArrayList可以加入null
2.ArrayList底层由数组实现数据存储
3.ArrayList基本等同于Vevtor,除了ArrayList是线程不安全的,但执行效率高,在多线程的情况下,不建议用ArrayList,即方法中没有synchronized修饰
4.ArrayList中维护了一个Object类型的数组elementData,  transient Object[] elementData;
transient表示瞬间,短暂的,表示该属性不会被序列化,会被忽略。什么是序列化,为什么要序列化 - 剑神西门吹雪 - 博客园

5.当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,没有分配空间
第一次添加,则扩容elementData为10,如需要再次扩容,即10个空间已经满了,继续添加则扩容elementData为1.5倍,即15个,当15个再满了,再添加时则数组扩容成22个


6.如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如国需要再次扩容,则直接扩容elementData为1.5倍

//ArrayList使用
public class Demo5 {
    public static void main(String[] args) {
        //创建集合
        ArrayList arrayList = new ArrayList();
        //添加元素
        Animal a1 = new Animal("小狗",5);
        Animal a2 = new Animal("小猫",6);
        arrayList.add(a1);
        arrayList.add(a2);
        //删除元素
        //arrayList.remove(a1);
        arrayList.remove(new Animal("小狗",5));
        /*
        这样不能删除集合中的这个元素,因为调用remove时候,会调用equals()方法,判断this==obj,
        即判断传入的这个对象是否等于先前集合里的那个,传入的是obj,集合中每个对象都传入这个obj,
        但==是判断的是地址,但这个是两个对象,所以不能删除
        要想删除的话需要重写Animal中equals方法
         */
        System.out.println(arrayList.size());
    }
}

class Animal{
    String name;
    int age;

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Animal{" +
                "name='" + name + '\'' +
                ", age='" + age + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object obj) {
        //判断是不是一个对象
        if(this == obj){
            return true;
        }
        //判断传入需要删除的对象是否为空
        if(obj==null){
            return false;
        }
        //判断传入的对象是否与集合对象是一个类型
        if(obj instanceof Animal){
            Animal animal = (Animal)obj;
            //比较属性
            if(animal.name == this.name && animal.age == this.age)
                return true;
            }
        return false;
        }
    }

 代码简述:ArrayList的操作,遍历跟上面list中的相同,这里着重介绍了利用重写equals方法去删除集合中的元素。

LinkedList

//LinkedList演示
public class Demo7 {
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList();
        Worker w1 = new Worker("xiaoz",15);
        Worker w2 = new Worker("xiaoa",19);
        linkedList.add(w1);
        linkedList.add(w2);
        linkedList.add(w2);
        System.out.println(linkedList.size());
        //删除
        //linkedList.remove(w1);
        //System.out.println(linkedList.size());
        //遍历
        //普通for
        System.out.print("普通for遍历:");
        for(int i = 0;i<linkedList.size();i++){
            System.out.println(linkedList.get(i));
        }
        //增强for
        System.out.print("增强for遍历:");
        for(Object w : linkedList){
            Worker wo = (Worker)w;
            System.out.println(wo);
        }
        //迭代器
        System.out.print("普通迭代器遍历:");
        Iterator it = linkedList.iterator();
        while (it.hasNext()){
            Worker wo = (Worker) it.next();
            System.out.println(wo);
        }
        //列表迭代器
        System.out.print("列表迭代器遍历:");
        ListIterator listIterator = linkedList.listIterator();
        while (listIterator.hasNext()){
            System.out.println(listIterator.next());
        }
        
        //判断
        System.out.println(linkedList.contains(w1));
        System.out.println(linkedList.isEmpty());
        //获取某个元素的下标
        System.out.println(linkedList.indexOf(w1));
    }
}

class Worker{
    String name;
    int age;

    public Worker(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Worker{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

代码简述:

 Vector

//Vecotr演示
public class Demo6 {
    public static void main(String[] args) {
        Vector vector = new Vector();
        vector.add("草莓");
        vector.add("芒果");
        //遍历,在jdk1.2之前遍历Vector用枚举器,与迭代器类似,枚举器没有删除的方法
        Enumeration en = vector.elements();
        while(en.hasMoreElements()){
            String o = (String)en.nextElement();
            System.out.println(o);
        }
    }
}

代码简述:演示Vector,主要是Vector的枚举器

Set接口?

特点:无序,无下标,元素不能重复

对Set接口的操作:

//以HashSet讲解Set接口的使用
        Set set = new HashSet();
        set.add("joker");
        set.add("lucy");
        set.add("joker");
        set.add(null);
        //存放数据无序(添加的顺序和取出的顺序不一致,但每次运行时取出的顺序一样)
        System.out.println(set);//[null, joker, lucy]
//使用迭代器遍历
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            String it = (String)iterator.next();
            System.out.println(it);
        }
        //增强for循环
        //增强for循环的底层也是迭代器
        for(Object s : set){
            System.out.println(s);
        }

代码简述:基本操作和遍历

HashSet

HashSet实际上是HashMap

HashSet hashSet = new HashSet();
        /*
        在执行add方法后,会返回一个Boolean值
        添加成功返回true
        添加失败返回false,当添加重复元素时,就会返回false
         */
        System.out.println(hashSet.add("xiaoa"));
        System.out.println(hashSet.add("xiaob"));
        System.out.println(hashSet.add("xiaoc"));
        System.out.println(hashSet.add("xiaoc"));
        hashSet.remove("xiaoa");

代码简述:add方法有Boolean返回值

//两个对象名字相同,但只是名字碰巧相同了,但不是一只猪,所以都可以加进去
        /*
        因为底层比对元素是否相同时,比对的是地址,这里如果想要两个名字相同的对象不能同时加入
        需要重写这个对象的equals方法
         */
        System.out.println(hashSet.add(new Pig("zhua")));//true
        System.out.println(hashSet.add(new Pig("zhua")));//true

        //第一个能加入,第二个加入不了
        System.out.println(hashSet.add(new String("zhub")));//true
        System.out.println(hashSet.add(new String("zhub")));//false
        System.out.println(hashSet);

代码简述:add方法的深入理解,需要看add方法的源码,这里时间关系先不看了,以后再看

TreeSet

TreeSet能自动按有序顺序排列对象,比如按132顺序加入元素,则可以输出123,按acb顺序加入元素,则可以输出abc。

Map接口

Map接口的特点

1.Map接口和Collection接口并列存在,用于保存具有映射关系的数据:key-value

2.Map中的key和value可以是任何引用类型的数据,会封装到HashMap$Node对象中

3.Map中的key不允许重复,原因和HashSet一样(需要追源码),value可以重复

5.key和value都可以为null,但是key为null只能有一个,value为null可以有多个

6.常用String类作为Map的key

7.key和value之间存在单向一对一的关系,即通过指定的key总能找到对应的value。

HashMap

特点:HashMap按无序形式存储对象 

public class Demo13 {
    public static void main(String[] args) {
        HashMap hashMap = new HashMap();
        hashMap.put("L1",1);
        hashMap.put("L2",2);
        hashMap.put("L3",3);
        System.out.println(hashMap.size());//3
        System.out.println(hashMap);//{L1=1, L2=2, L3=3}
        hashMap.remove("L1");
        System.out.println(hashMap.size());//2
        System.out.println(hashMap);//{L2=2, L3=3}
        System.out.println(hashMap.get("L2"));//2
        System.out.println(hashMap.size());//2
        hashMap.clear();
        System.out.println(hashMap.size());//0
    }
}

代码简述:HashMap的简单应用

TreeMap

特点:TreeMap按有序顺序创建对象,有序顺序可以改善对象的检索过程

public class Demo14 {
    public static void main(String[] args) {
        TreeMap treeMap = new TreeMap();
        treeMap.put(1,"a");
        treeMap.put(3,"c");
        treeMap.put(4,"d");
        treeMap.put(2,"l");
        System.out.println(treeMap);//{1=a, 2=l, 3=c, 4=d}
    }
}

代码简述:TreeMap的简单应用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值