Java集合

Java集合

Collection接口和常用方法

  • Collection接口实现类的特点

    public interface Collection< E > extends lterable < E >
    1、 Collection实现子类可以存放多个元素,每个元素可以是Object
    2、有些Collection的实现类,可以存放多个元素,每个元素可以是Object
    3、有些Collection的实现类,有些是有序的(List)有些不是有序(Set)
    4、Collection接口没有直接的实现子类,是通过它的子接口Set 和 List来实现的
  • Collcetion接口常用方法

    1、add:添加单个元素
    2、remove:删除指定元素
    3、contains:查找元素是否存在
    4、size:获取元素个数
    5、isEmpty:判断是否为空
    6、clear:清空
    7、addAll:添加多个元素
    8、containsAll:查找多个元素是否都存在
    9、removeAll:删除多个元素
  • Collection接口遍历元素方式1-使用Iterator(迭代器)

    1、Iterator对象称为迭代器,主要用于 遍历Collection集合的元素。
    2、所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iteraror接口的对象,既可以返回一个迭代器。
    3、Iterator 的结构图。
    4、Iterator仅用于遍历集合,Iterator本身并不存放对象。
  • 迭代器的执行原理

    //得到一个集合的迭代器
    Iterover itreover = coll.iterator();
    //判断是否还有下一个元素
    hasNext();
    while(iterator.hasNext()){
        //next()作用:1、下移,并将下移以后集合位置上的元素返回
        System.out.println(iterator.next());
    }
    
    注意:在调用iterator.next()方法之前必须要调用iterator.hasNext()进行检测,若不调用,且吓一跳记录无效,直接调用it.next()会抛出NoSuchElementException异常。
    package com.shuai.collection;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Iterator;
    
    public class CollectionIterator {
    
        @SuppressWarnings({"all"})
        public static void main(String[] args) {
    
            Collection col = new ArrayList();
    
            col.add(new Book("三国演义", "罗贯中", 16.8));
            col.add(new Book("水浒传", "施耐庵", 18.8));
            col.add(new Book("红楼梦", "曹雪芹", 19.8));
    
            //System.out.println("col="+col);
    
            Iterator iterator = col.iterator();
    
            //使用while循环遍历,快速生成 While 快捷键 itit 提示快捷键 ctrl + j
            while (iterator.hasNext()) {//判断是否还有数据
                //返回下一个元素,类型是Object
                Object obj =  iterator.next();
                System.out.println("obj"+obj);
            }
    
            //当退出while循环后,这是iteroter迭代器,指向最后一个元素
            //iterator.next();//报出NoSuchElemenException异常
            //如果希望再次遍历,需要重制迭代器
            iterator = col.iterator();
            System.out.println("===============第二次遍历===============");
            while (iterator.hasNext()) {
                Object obj = iterator.next();
                System.out.println("obj"+obj);
            }
        }
    }
    
    class Book {
    
        private String name;
        private String author;
        private double price;
    
        public Book(String name, String author, double price) {
            this.name = name;
            this.author = author;
            this.price = price;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAuthor() {
            return author;
        }
    
        public void setAuthor(String author) {
            this.author = author;
        }
    
        public double getPrice() {
            return price;
        }
    
        public void setPrice(double price) {
            this.price = price;
        }
    
        @Override
        public String toString() {
            return "Book{" +
                    "name='" + name + '\'' +
                    ", author='" + author + '\'' +
                    ", price=" + price +
                    '}';
        }
    }
    
  • Collection接口遍历对象方式2-for循环增强。

    增强for循环,可以代替iterator迭代器,特点:增强for循环就是简化版的iterator,本质一样,只能用于遍历集合或数组。
    基本语法:
    for(元素类型 元素名:集合名或数组名){
        访问元素
    }
    
    package com.shuai.collection;
    
    import java.util.ArrayList;
    import java.util.Collection;
    
    public class CollectionFor {
    
        public static void main(String[] args) {
    
            Collection col = new ArrayList();
    
            col.add(new Book("三国演义", "罗贯中", 16.8));
            col.add(new Book("水浒传", "施耐庵", 18.8));
            col.add(new Book("红楼梦", "曹雪芹", 19.8));
            col.add(new Book("西游记", "吴承恩", 15.8));
    
            //1、使用增强for,在Collection集合
            //2、增强for,底层仍然是迭代器
            //3、增强for可以理解成就是简化版的迭代器
            //4、快捷方式 I + Enter
            for (Object book:col){
                System.out.println("book="+book);
            }
        }
    }
    
    
    练习:编写程序CollectionExercise.java
    • 1、创建3个Dog{name,age}对象,放入到ArrayList中,赋给List引用
    • 2、用迭代器和增强for循环两种方式来遍历
    • 3、重写Dog的toString方法,输出name和age
    package com.shuai.collection;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    
    public class CollectionExercise {
        @SuppressWarnings({"all "})
        public static void main(String[] args) {
    
            List list = new ArrayList();
    
            list.add(new Dog("大白", 3));
            list.add(new Dog("小黑", 2));
            list.add(new Dog("尼克", 6));
    
            for (Object dog : list) {
                System.out.println("dog=" + dog);
            }
    
            System.out.println("=======使用迭代器循环遍历======");
    
            Iterator iterator = list.iterator();
    
            while (iterator.hasNext()) {
                Object Dog = iterator.next();
                System.out.println("Dog=" + Dog);
    
            }
        }
    }
    
    class Dog {
    
        private String name;
        private int age;
    
        public Dog(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Dog{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    

List接口和常用方法

  • List接口是Collection接口的子接口 List.java
    1、List集合中元素有序(添加顺序个和取出顺序一致)、且可重复。
    2、List集合中的每一元素都有其对应的顺序索引,即支持索引。
    3、List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素。
    4、JDK API中List接口的实现类常用的有:ArrayList、LinkedList和Vector。
  • List接口的常用方法 ListMethod.java,
    List集合离添加了一些根据索引来操作集合元素的方法
    package com.shuai.collection;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class ListMethod {
        @SuppressWarnings({"all"})
        public static void main(String[] args) {
            List list = new ArrayList();
    
            list.add("刘备");
          list.add("张飞");
    
            //1、void add(int index,Object ele):在index位置插入ele元素
            list.add(1,"关羽");
            System.out.println("list=" + list);
    
            //2、boolean addAll(int index,Collection eles):从index位置开始将eles中的所有元素添加进来
            List list1 = new ArrayList();
            list1.add("马超");
            list1.add("赵云");
            list.addAll(1,list1);
            System.out.println("list=" + list);
    
            //3、Object get(int index):获取指定index位置的元素
            System.out.println("list=" + list);
            System.out.println(list.get(1));
    
            //4、int indexOf(Object obj):返回obj在当前集合中首次出现的位置
            System.out.println(list.indexOf("张飞"));
    
            //5、int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置
            list.add("赵云");
            System.out.println("list=" + list);
            System.out.println(list.lastIndexOf("赵云"));
    
            //6、Object remove(int index):一处指定index位置的元素,并返回此元素
            list.remove(0);
            System.out.println("list=" + list);
    
            //7、Object set(int index,Object ele):设置指定index位置的元素为ele,相当于是替换
            System.out.println("list="+list);
            list.set(1,"黄忠");
            System.out.println("list=" + list);
    
            //8、List subList(int fromIndex,int toIndex):返回从fromIndex到toIndex位置的子集合
            //注意:返回的子集合 fromIndex <= subList < toIndex
            List returnList = list.subList(1, 4);
            System.out.println("returnList=" + returnList);
        }
    }
    
    
    练习:
    package com.shuai.collection;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    
    public class ListExercise {
        @SuppressWarnings("all")
        public static void main(String[] args) {
    
            List list = new ArrayList();
    
            //用for循环在list集合中添加十个以上“Hello”
            for (int i = 0; i < 11; i++) {
                list.add("hello" + i);
            }
            System.out.println("list=" + list);
    
            //在2号位插入一个“Niko”;
            list.add(1,"Nike");
            System.out.println("list=" + list);
    
            //获得第五个元素;
            System.out.println("第五个元素=" + list.get(4));
    
            //删除第六个元素;
            list.remove(5);
            System.out.println("list="+ list);
    
            //修改第七个元素
            list.set(6,"修改");
            System.out.println("list="+ list);
    
            //使用迭代器遍历list集合
            Iterator iterator = list.iterator();
            while (iterator.hasNext()) {
                Object obj =  iterator.next();
                System.out.println(obj);
            }
        }
    }
    

ArrayList底层结构和远吗分析

  • ArrayList的注意事项
    1、permits all elements , including null , ArrayList 可以加入null,并且多个
    2、ArrayList 是由数组来实现数据存储的
    3、ArrayList 基本等同于Vector , 除了ArrayList是线程不安全(执行效率高),在多线程的情况下,不建议使用ArrayList
package com.shuai.collection;

import java.util.ArrayList;

public class ArrayListDetail {
    public static void main(String[] args) {

        //ArrayList 是线程不安全的,可以看源码,没有 synchronized
        /*
            public boolean add(E e) {
                ensureCapacityInternal(size + 1);  // Increments modCount!!
                elementData[size++] = e;
                return true;
            }
         */
        ArrayList arrayList = new ArrayList();

        arrayList.add(null);
        arrayList.add("make");
        arrayList.add(null);

        System.out.println(arrayList);
    }
}
### ArrayList底层结构和源码分析
  • ArrayList的底层操作机制源码分析(重点,难点)
    1、ArrayList中维护了一个Object类型的数组elementData.[debug 看源码]transient Object[] elementData;
    2、当创建对象时,如果使用的是无参构造器,则初始elementData容量为0(jdk7是10)
    3、当添加元素时:先判断是否需要扩容,如果需要扩容,则调用grow方法,否则直接添加元素到合适的位置
    4、如果使用的是无参构造器,如果第一次添加,需要扩容的话,则扩容elementData为10,如果需要再次扩容的话,则扩容elementData为1.5倍
    5、如果使用的是指定容器capacity的构造器,则初始elementData容量为capacity
    6、如果使用的是指定容器capacity的构造器,如果需要扩容,则直接扩容elementData为1.5倍

Vector底层结构和源码剖析

  • Vcector的基本介绍
    1、 Vector类的定义说明
    public class Vectoir<E>
    extends AbstractList<E>
    implements List<E>,RandomAccess,Cloneable,Serializable
    
    
    2、Vector底层也是一个对象数组,protected Object[] elementData;
    3、Vector是线程同步的,即线程安全,Vector类的操作方法带有synchronized
    public synchronized E get(int index){
        if(index >= elementCount){
            throw new ArrayIndexOutOfBoundsExecption(index);
         	return elementData(index);
        }
    }
    
    
    4、在开发中,需要线程同步安全时,考虑使用Vector

Vector底层结构和ArrayList的比较

  • Vector和ArrayList的比较
    底层结构版本线程安全(同步)效率扩容倍数
    ArrayList可变数组jdk1.2不安全,效率高如果有参构造1.5倍;如果是无参第一次10从第二次开始按1.5倍扩容
    Vector可变数组jdk1.0安全,效率不高如果是无参,默认10,满后,按2倍扩容;如果指定大小,则每次直接按2倍扩

LinkedList底层结构

  • LinkedList的全面说明
    1、LinkedList实现了双向链表和两端队列的特点
    2、可以添加任意元素(元素可以重复),包括null
    3、线程不安全,没有实现同步
  • LinkedList底层操作机制
    1、LinkedList底层维护了一个双向链表
    2、LinkedList中维护了两个属性first和last分别指向首节点和尾节点
    3、每个节点(Node对象)里面又维护了prev、next、item三个属性,其中通过prev指向前一个,通过next指向后一个节点。最终实现双向链表。
    4、说以LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高

ArrayList 和 LinkedList比较

  • ArrayList和LinkdedList的比较
底层结构增删的效率改查的效率
ArrayList可变数组较低,数组扩容较高
LinkedList双向链表较高,通过链表追加较低
  • 如何选择ArrayList和LinkedList:
    1、改查造作较多,选择ArrayList
    2、增删操作较多,选择LinkedList
    3、一般来说,在程序中。80%-90%都是查询,因此大部分情况下会选择ArrayList
    4、在一个项目中,根据业务灵活选择,也可能这样,一个模块使用的是ArrayList,另外一个模块是LinkedList。

Set接口和常用方法

  • Set接口基本介绍
  • 1、无序(添加和取出的顺序不一样),没有索引
  • 2、不允许重复元素,所以最多包含一个null
package com.shuai.set_;

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

public class SetMethod {
    public static void main(String[] args) {

        //1、以 Set 接口的实现类 HashSet 来讲解Set 接口的方法
        //2、set 接口的实现类的对象(Set接口对象),不能存放重复的元素,可以添加一个null
        //3、set 接口对象存放数据是无序的(即添加的顺序和取出的顺序不一致)
        //4、注意:取出的顺序的顺序虽然不是添加的顺序,但是他是固定的
        Set set = new HashSet();
        set.add("make");
        set.add("faker");
        set.add("ale");
        set.add("jack");
        set.add("faker");
        set.add(null);
        set.add(null);

        System.out.println("set=" + set );

        for (int i = 0; i < 10; i++) {
            System.out.println("set=" + set );
        }

        //遍历
        //使用迭代器
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            Object obj =  iterator.next();
            System.out.println("obj=" + obj );
        }

        //增强for循环遍历
        for (Object o :set) {
            System.out.println("o=" + o);
        }
    }
}

Set接口实现类-HashSet

  • HashSet的全面说明
    1、HashSet实现了Set接口
    2、HashSet实际上是HashMap
    public HashSet(){
        map = new HashMap<>();
    }
    
    
    3、可以存放null值,但是只能有一个null
    4、HashSet不保证元素是有序的,取决于hash后,再确定索引的结果
    5、不能有重复的元素/对象
package com.shuai.set_;

import java.util.HashSet;

public class HashSet01 {
    public static void main(String[] args) {

        HashSet set = new HashSet();

        //1、在执行add方法之后,会返回一个boolean值
        //2、添加成功,返回ture,否则返回false
        //3、可以通过remove指定删除哪个对象
        System.out.println(set.add("make"));
        System.out.println(set.add("key"));
        System.out.println(set.add("faker"));
        System.out.println(set.add("jack"));
        System.out.println(set.add("key"));
        System.out.println(set.add("sky"));

        set.remove("key");
        System.out.println("set=" + set);

        set = new HashSet();
        //4、HashSet不能添加相同的元素/数据
        set.add("Rose");//添加成功
        set.add("Rose");//加入不了
        set.add(new Dog("noke"));//OK
        set.add(new Dog("noke"));//OK
        System.out.println("set=" + set);

        set.add(new String("mata"));//OK
        set.add(new String("mata"));//加入不了

        System.out.println("set=" + set);
    }
}

class Dog {

    private String name;

    public Dog(String name) {
        this.name = name;
    }

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

Set接口实现类-HashSet

  • HashSet底层机制说明
  • HashMap底层是(数组+链表+红黑树)
package com.shuai.set_;

public class HashSetStructure {
    public static void main(String[] args) {
        //模拟一个HashSet的底层(HashMap 的底层结构)

        //创建一个数组,数组的类型是 Node
        //有些人把Node[] 数组称为    表
        Node[] table = new Node[16];

        //3、创建结点
        Node jack = new Node("jack",null);

        table[2] = jack;//将jack 放到 table表的索引为2的位置
        Node faker = new Node("faker",null);
        jack.next = faker;//将faker结点挂载到jack
        Node meike = new Node("meike",null);
        faker.next = meike;//将meike// 结点挂载到faker

        Node sky = new Node("sky",null);
        table[3] = sky;//将sky 放到 table表的索引为3的位置
        System.out.println("table=" + table);


    }
}

class Node {//结点,储存数据,可以指向下一个结点,从而形成链表
    Object item;//存放数据
    Node next;//指向下一个结点

    public Node(Object item, Node next) {
        this.item = item;
        this.next = next;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TonkiRex

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值