JAVA 集合类

集合

一、集合的理解和好处

前面我们保存多个数据使用的是数组,那么数组有不足的地方

数组的不足之处:

  1. 长度开始时必须指定,而且一旦指定,不能更改
  2. 保存的必须为同意类型的元素
  3. 使用数组进行增加/删除 比较麻烦


集合的好处

  1. 可以动态保存任意多个对象,使用比较方便!
  2. 提供了一系列方便的操作对象的方法:add、remove、set、get
  3. 使用集合添加、删除新元素的代码更加简洁了

二、集合框架图

要求:背下来

集合主要分为两组

  • 单列集合:在集合中放的都是单个单个的元素
  • 双列集合:剑字段一起存放
  1. Collection 接口有两个重要的接口,List和Set,他们的实现子类都是单列集合
  2. Map 接口的实现子类是双列集合,存放K-V

单列集合:Collection

双列集合:Map

package com.hspedu.collection_;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * @author DL5O
 * @version 1.0
 */
public class Collection_ {
    @SuppressWarnings("all")
    public static void main(String[] args) {
//        Collection
//        Map
        ArrayList arrayList = new ArrayList();
        arrayList.add("jack");
        arrayList.add("tom");

        HashMap hashMap = new HashMap();
        hashMap.put("NO1","北京");
        hashMap.put("NO2","伤害");
    }
}


三、Collection接口和常用方法

1.Collection接口实现的特点

public interface Collection<E> extends Iterable<E>

  1. collection实现子类可以存放多个元素,每个元素可以是Object
  2. 有些Collection的实现类,可以存放重复的元素,有些不可以
  3. 有些Collection的实现类,有些是有序的(List),有些不是有序(Set)
  4. Collection接口没有直接的实现子类,是通过它的子接口Set和 List来实现的

2.Collection接口常用方法

package com.hspedu.collection_;

import java.util.ArrayList;
import java.util.List;

/**
 * @author DL5O
 * @version 1.0
 */
public class ArrayList_ {
    @SuppressWarnings("all")
    public static void main(String[] args) {
        List list = new ArrayList();
        //add 添加单个元素
        list.add("jack");
        list.add(10);//这里有个自动装箱的过程,会装箱为包装类,list.add(new Integer(10))
        list.add(true);//同上
        System.out.println("list=" + list);//list=[jack, 10, true]

        //remove:删除指定元素
        //list.remove(0);//删除第一个元素
        //也可以
        list.remove("jack");
        System.out.println("list=" + list);

        //contains:查找元素是否存在
        System.out.println(list.contains(10));//T

        //size:获取元素个数
        System.out.println(list.size());//2

        // isEmpty:判断是否为空
        System.out.println(list.isEmpty());//F

        // clear:清空
//        list.clear();
//        System.out.println("list=" + list);//list=[]

//         addAll:添加多个元素
        ArrayList list2 = new ArrayList();
        list2.add("红楼梦");
        list2.add("三国演义");
        list.addAll(list2);
        System.out.println("list=" + list);

        // containsAll:查找多个元素是否都存在
        System.out.println(list.containsAll(list2));//T

        // removeAll:删除多个元素
        list.add("聊斋");
        list.removeAll(list2);
        System.out.println("list=" + list);//[10, true, 聊斋]
    }
}

3.Collection 接口遍历元素方式 1-使用 Iterator(迭代器)

介绍:只要是实现了Collection接口的子类都可以获取到Iterator这个迭代器,然后用这个迭代器遍历这个集合的所有元素

  1. Iterator对象称为迭代器,主要用于遍历Collection集合中的元素

  2. Collection接口的集合类都有一个iterator()方法,用来返回一个实现了Iterator接口的对象,即返回一个迭代器

  3. Iterator的执行原理

image-20220305152607514

  • 得到一个数组,从栈顶开始依次下移指针,直到栈底

  • next()的作用:

    • 下移
    • 将下移以后集合位置上的元素返回

Iterator(迭代器遍历)

注意:

  • 在调用iterator.next()方法之前必须要调用iterator.hasNext()进行检测。若不调用,且下一条记录无效,直接调用it.next()会抛出异常。
package com.hspedu.collection_;

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

/**
 * @author DL5O
 * @version 1.0
 */
@SuppressWarnings("all")
public class CollectionIterator01 {
    public static void main(String[] args) {
        Collection col = new ArrayList();

        col.add(new Book("三国演义", "罗贯中", 10.1));
        col.add(new Book("小李飞刀", "古龙", 5.1));
        col.add(new Book("红楼梦", "曹雪芹", 34.6));
        col.add("jack");

//        System.out.println("col" + col);


        //现在想一本一本的遍历这个 col 集合
        //1.先得到这个集合对应的迭代器
        Iterator iterator = col.iterator();
        //2.使用while循环遍历
        /*while (iterator.hasNext()) {//判断是否还有数据
            //next方法返回的数据,是下一个元素,类型是Object,
            //编译类型 Object
            //运行类型 取决于真正存放的类型
            Object obj = iterator.next();
            System.out.println("obj=" + obj);
        }*/

        //快捷键,快速生成 ==> itit
        //快捷键提示 ctrl + j
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println("obj=" + next);
        }
        //3.当退出while循环后,这时iterator迭代器,指向的是最后的元素
        //iterator.next();//报异常:NoSuchElementException

        //4.如果需要再次遍历,需要重置迭代器
        System.out.println("====第二次====");
        iterator = col.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println("obj=" + next);
        }
    }
}

@SuppressWarnings("all")
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 +
                '}';
    }
}

for 循环增强遍历

基本语法:

for(元素类型 元素名:集合或数组名){
	访问元素
}
package com.hspedu.collection_;

import java.util.ArrayList;
import java.util.Collection;

/**
 * @author DL5O
 * @version 1.0
 */
public class CollectionFor01 {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        Collection col = new ArrayList();
        col.add(new Book("三国演义", "罗贯中", 10.1));
        col.add(new Book("小李飞刀", "古龙", 5.1));
        col.add(new Book("红楼梦", "曹雪芹", 34.6));

        //使用增强for循环
        //1.使用增强for,在Collection集合
        //2.增强for,底层仍然是迭代器
        //3.可以理解成:简化版的迭代器遍历
        //快捷键 I
        for (Object o :col) {
            System.out.println(o);
        }


        //增强for可以用在数组上
        int[] nums = {1, 23, 4, 5};
        for (int i : nums) {
            System.out.print(i + " ");
        }
    }
}

快捷键:大写的I


四、List接口和常用方法

  1. List集合类中的元素是有序的(添加顺序和取出顺序一致)、且可重复
  2. List 集合中的每个元素都有其对应的顺序索引,即支持索引
  3. List接口常用的是ArrayListLinkedListVector
package com.hspedu.list_;

import java.util.ArrayList;
import java.util.List;

/**
 * @author DL5O
 * @version 1.0
 */
public class ListMethod {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("张三丰");
        list.add("贾宝玉");
        // void add(int index, Object ele):在 index 位置插入 ele 元素
        //在 index = 1 的位置插入一个对象
        list.add(1,"大龙");
        System.out.println("list=" + list);
        // boolean addAll(int index, Collection eles):从 index 位置开始将 eles 中的所有元素添加进来
        List list2= new ArrayList();
        list2.add("jack");
        list2.add("tom");
        list.addAll(1,list2);
        list.add("大龙");

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

        //Object get(int index):获取指定 index 位置的元素
        System.out.println("1 index element=" + list.get(1));//jack

        //int indexOf(Object obj):返回 obj 在集合中首次出现的位置
        System.out.println("大龙 index=" + list.indexOf("大龙"));//3

        //int lastIndexOf(Object obj):返回 obj 在当前集合中末次出现的位置
        System.out.println("大龙 lastIndex=:"+list.lastIndexOf("大龙"));//5

        //Object remove(int index):移除指定 index 位置的元素,并返回此元素
        list.remove("张三丰");
        System.out.println("list=" + list);

        //Object set(int index, Object ele):设置指定 index 位置的元素为 ele , 相当于是替换
        list.set(1,"玛丽");
        System.out.println("list=" + list);


        //List subList(int fromIndex, int toIndex):返回从 fromIndex 到 toIndex 位置的子集合
        // 注意:这里没有包索引为3的对象元素取到,所以返回的集合是[formIndex,toIndex);
        List returnList = list.subList(1, 3);
        System.out.println("returnList" + returnList);//[玛丽, 大龙]
    
    }
}

1.List的三种遍历方法

package com.hspedu.list_;

import java.util.*;

/**
 * @author DL5O
 * @version 1.0
 */
public class ListFor {
    @SuppressWarnings("all")
    public static void main(String[] args) {
        //接口实现的子类 LinkedList ArrayList Vector
        List list = new Vector();
      /*  List list = new ArrayList();
        List list = new LinkedList();*/
        list.add("jack");
        list.add("tom");
        list.add("鱼香肉丝");
        list.add("北京烤鸭");

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


        //2.使用增强for循环进行遍历
        // 底层仍然是实现了Iterator这个接口,然后进行相关方法的调用,相当于简化版的iterator迭代器
        System.out.println("====使用增强for循环进行遍历====");
        for (Object o :list) {
            System.out.println("obj=" + o);
        }

        //3.使用普通的for
        for (int i = 0; i < list.size(); i++) {
            System.out.println("obj=" + list.get(i));
        }

    }
}

2.课堂练习

package com.hspedu.list_;

import java.util.ArrayList;
import java.util.List;

/**
 * @author DL5O
 * @version 1.0
 */
public class ListExercise01 {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(new Book("红楼梦", "曹雪芹", 100));
        list.add(new Book("西游记", "吴承恩", 10));
        list.add(new Book("水浒传", "施耐庵", 19));
        list.add(new Book("三国", "罗贯中", 80));

        System.out.println("====排序前====");
        for (Object book : list) {
            System.out.println(book);
        }

        sort(list);
        System.out.println("====排序后====");
        for (Object book : list) {
            System.out.println(book);
        }
    }

    //价格要求是从小到大
    //利用list.set 实现集合元素的交换
    public static void sort(List list) {
        int listSize = list.size();
        for (int i = 0; i < listSize - 1; i++) {
            for(int j = 0 ; j < listSize - 1 - i;j++){
                Book book1 = (Book)list.get(j);//取出来后的对象是Object类型的,因此这里要向下转型
                Book book2 = (Book)list.get(j+1);

                if(book1.getPrice() > book2.getPrice()){
                    list.set(j,book2);
                    list.set(j+1,book1);
                }
            }
        }
    }
}

@SuppressWarnings("all")
class Book {
    private String name;
    private String author;
    private double price;


    public Book(String name, String author, double price) {
        this.name = name;
        this.price = price;
        this.author = author;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    @Override
    public String toString() {
        String formatstr= "名称:%s\t价格:%.2f\t作者:%s\t";
        String info = String.format(formatstr,this.name,this.price,this.author);
        return info;
    }
}

五、Set接口和常用方法

Set接口介绍:

  1. 无序(添加和取出的顺序不一致),没有索引
  2. 不允许重复元素,所以最多包含一个null
  3. JDK API中Set接口实现的类又


1.Set接口的常用方法

  • 和 List 接口一样, Set 接口也是 Collection 的子接口,因此,常用方法和 Collection 接口一样

2.Set接口的遍历方法

同Collection的遍历方法一样

  1. 可以使用迭代器
  2. 增强for

注意:

  • 不能使用索引的方式来获取。

3.Set接口的常用方法

注意:

  1. set接口的实现类对象(set接口对象),不能存放重复的元素

  2. null可以加入到集合中

  3. set 接口对象存放数据是无序(即添加的顺序和取出的顺序不一致)的

  4. 取出的顺序的是固定的,虽然不是添加的顺序,但是它的固定的

package com.hspedu.set_;

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

/**
 * @author DL5O
 * @version 1.0
 */
public class SetMethod {
    public static void main(String[] args) {

        // 解读:
        // 1.以 Set 接口的实现类 HashSet 来讲解 Set 接口的方法
        // 2.set 接口的对象
        Set set = new HashSet();
        set.add("john");
        set.add("lucy");
        set.add("jahn");//重复
        set.add("john");
        set.add("ywl");
        set.add("ywl");
        set.add(null);//空
        set.add(null);//再次添加空

        System.out.println(set);//[null, john, jahn, lucy]
        System.out.println(set);//[null, john, jahn, lucy]

        //遍历
        //方式一:使用迭代器
        System.out.println("===迭代器遍历===");
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            Object obj =  iterator.next();
            System.out.println("obj=" + obj );
        }
        //方式二:增强for
        System.out.println("===增强for===");
        for (Object o :set) {
            System.out.println("o=" + o);
        }

    }
}

六、如何选择集合实现类

  1. 先判断存储的类型(一组对象[单列]或一组键值对[双列])
  2. 一组对象[单列]:Collection接口
    • 允许重复:List
      • 增删多:LinkdList [底层维护了一个双向链表]
      • 改查多:ArrayList [底层维护了Object类型的可变数组]
    • 不允许重复:Set
      • 无序:HashSet[底层 HashMap,维护的是一个哈希表即(数组+链表+红黑树)]
      • 排序:TreeSet
      • 插入和取出顺序一致:LinkedHashSet[底层LinkedHashMap的底层HashMap],维护的数组+双向链表
  3. 一组键值对:Map
    • 键无序:HashMap[底层是:哈希表 jdk7:数组+链表 jdk8:数组+链表+红黑树]
    • 键排序:TreeMap
    • 键插入和取出顺序一致:LinkedHashMap
    • 读取文件:Properties
posted @ 2022-03-09 22:52  DL50  阅读(34)  评论(0编辑  收藏  举报