集合详解、代码详解

    • 概述

相当于一个容器。

Java的集合框架是由很多接口、抽象类、具体类组成的,都位于java.util包中。

数组就是一个容器,但它删除元素麻烦;长度不能改变;容量不够时,需进行扩容。

而程序运行时,数据是时刻变化的,为满足各种变化的数据存储需求,在Java中封装了许多类类存储不同数据,这些类称为集合类。

2.单列集合 Collection

其子接口Set和List分别定义了存储方式。

● List 中的数据对象有顺序且可以重复。

● Set 中的数据对象没有顺序且不可以重复。

2.1 List

接口实现类的集合,可存储重复元素;有序;可通过索引操作元素

List继承了Collection接口,有三个实现的类

● ArrayList :数组列表

数组每个空间是连续的,所以查询方便,直接通过下标获取指定位置元素;但从中间增添删除元素较

麻烦,因增添删除后,其他元素要位移。

import java.util.ArrayList;

public class ArrayListDemo1 {
    /*
  
        ArrayList  数组列表  动态增添数组
        ArrayList<E>  使用泛型的语法,为集合存储数据设定数据类型

        底层数组    transient Object[] elementData;
        add();  默认向集合末尾添加元素,首次底层会初始化一个长度为10的数组,
                当集合满了,会自动扩容为原来的1.5倍。

     */
    public static void main(String[] args) {
        //ArrayList<String> a=new ArrayList<String>();
        ArrayList<String> a=new ArrayList();
        a.add("a");//末尾添加
        a.add("b");
        a.add("c");
        a.add("d");
        a.add("e");
        a.add("f");
        a.add("g");
        a.add("h");
        a.add("i");
        a.add("j");
        a.add("k");
        a.add(0,"A");//向指定位置添加
        //a.clear();//清空
        a.remove(1);//删除指定位置元素
        a.remove("a");//删除指定内容元素  第一个出现的
        System.out.println(a.size());//获取集合中元素个数
        System.out.println(a.get(2));
        System.out.println(a);
        System.out.println(a.contains("f"));
        System.out.println(a.isEmpty());
        a.ensureCapacity(20);//扩容为指定容量
        System.out.println(a.indexOf("b"));//从前向后  获取指定元素首次位置
        System.out.println(a.lastIndexOf("b"));//从后向前  获取元素首次位置
        a.set(1,"A");
        System.out.println(a);
        Object[] o=a.toArray();//将集合转为Object类
        System.out.println(o.length);
        String[] as=a.toArray(new String[a.size()]);//将集合转为指定类型
        System.out.println(Arrays.toString(as));
    }
}
● LikedList: 链表列表

每一个数据存储在一个Node类中 Node节点

链表结构,对外提供头尾节点,查询元素慢,必须从头或尾部开始;

从中间删除元素块,只需改变next节点的内存地址即可,元素不位移。

import java.util.LinkedList;

public class LinkedListDemo {
   
    public static void main(String[] args) {
        LinkedList<String> l=new LinkedList<>();
        l.add("a");
        l.add("b");
        l.add("c");
        l.add("d");
        l.add(1,"A");
        System.out.println(l.get(2));
        l.remove(1);
        l.remove("3");
        System.out.println(l.size());
        //LinkedList  可实现队列和栈结构容器
        l.addFirst("A");
        l.addLast("D");
        System.out.println(l.getFirst());
        System.out.println(l.getLast());
        System.out.println(l.removeFirst());
        System.out.println(l.removeLast());
        System.out.println(l);
    }
}
Vector : 数组列表(线程安全的)
import java.util.Vector;

public class VectorDemo {
    /*
        List
            Vector 数组列表
            synchronized  线程安全的

     */
    public static void main(String[] args) {
        Vector<Integer> v=new Vector();
        v.add(1);
        v.add(2);
        v.add(3);
        v.add(4);
        v.add(5);
        v.add(6);
        v.add(7);
        v.add(8);
        v.add(9);
        v.add(10);
        v.add(11);
        v.add(12);
        System.out.println(v);//[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
    }
}
List接口集合迭代

● for循环遍历

●增强for循环的遍历

import java.util.ArrayList;

public class LinkedFor {
    public static void main(String[] args) {
        ArrayList<String> a=new ArrayList<>();
        a.add("a");
        a.add("b");
        a.add("c");
        a.add("d");
        //for 允许删除元素,注意元素的位移及索引变化
        for(int i=0;i<a.size();i++){
            String s=a.get(i);
            System.out.println(s);
        }
        //增强循环  不允许删除元素  高度封装
        for(String s:a){
            System.out.println(s);
        }
    }
}

● 迭代器遍历(Iterator)

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;

public class LinkedFor2 {
    public static void main(String[] args) {
        ArrayList<String> a=new ArrayList<>();
        a.add("a");
        a.add("b");
        a.add("c");
        a.add("d");
        /*
        对集合进行遍历的迭代器
         */
        Iterator<String> it=a.iterator();
        while(it.hasNext()){//判断有无下一个元素
            String item=it.next();//取出元素
            if(item.equals("b")){
                it.remove();
            }
        }
        System.out.println(a);//[a, c, d]
/*
         //获取集合的迭代器
        ListIterator<String> it=a.listIterator();
        while(it.hasNext()){
            String item=it.next();
            System.out.println(item);
        }*/
        //从后向前进行遍历   给定开始的位置
        ListIterator<String> it=a.listIterator(a.size());//4  0-3
        while(it.hasPrevious()){
            String item=it.previous();
            System.out.println(item);
            /*输出
                d
                c
                b    
                a

            */


        }
    }
}

2.2 Set

Set接口继承了Collection接口。 Set中所存储的元素是不重复的,但是是无序的, Set中的元素是没有索引的 。 Set接口有两个实现 类。

● HashSet

元素不能重复,即彼此调用equals方法比较,都返回false。 底层数据结构是哈希表+链表 哈希表依赖于哈希值存储 。

import java.util.HashSet;

public class HashSetDemo2 {
    /*
    HashSet:不能存储重复元素,存储元素无序
    判断元素是否重复:不直接用equals()进行判断,因效率低;
    而是先调用hashCode(),计算hash值,判断两整数是否相等;
    但不同内容计算的hash值可能相同,当hash值相同时,再调用equals()判断
     */
    public static void main(String[] args) {
        HashSet<String> hs = new HashSet<>();
        hs.add("as");//110  设哈希值为110
        hs.add("as");//110
        hs.add("通话");//1179410   与下面的元素哈希值相同
        hs.add("种地");//1179410
        System.out.println(hs);//[as, 通话, 种地]
    }
}

存储自定义对象

import java.util.Objects;
package com.albb.javaCollection.Set;

import java.util.HashSet;

public class HashSetDemo3 {
    public static void main(String[] args) {
        /*
        存储自定义对象时,类中默认没有重写hashCode()和equals(),
        都是调用Object类中,其中的hashCode()默认获取对象的内存地址
         */
        Car car1=new Car(101,"宝马1");
        Car car2=new Car(102,"宝马2");
        Car car3=new Car(103,"宝马3");
        Car car4=new Car(101,"宝马1");
        Car car5=new Car(104,"宝马4");
        HashSet<Car> hs=new HashSet<>();
        hs.add(car1);
        hs.add(car2);
        hs.add(car3);
        hs.add(car4);
        hs.add(car5);
        System.out.println(hs);//[Car{num=101, name='宝马1'}, Car{num=102, name='宝马2'}, Car{num=103, name='宝马3'}, Car{num=104, name='宝马4'}]

    }
}


public class Car implements Comparable<Car>{
    private int num;
    private  String name;
    public Car(int num,String name){
        super();
        this.num=num;
        this.name=name;
    }

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Car car = (Car) o;
        return num == car.num &&
                Objects.equals(name, car.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(num, name);
    }
    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public String getName() {
        return name;
    }

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

不能储存重复元素,按值的自然顺序排列 以给Set集合中的元素进行指定方式的排序。存储的对象必须实现Comparable接口。 TreeSet底层数据结构是二叉树(红黑树是一种自平衡的二叉树)。

import java.util.TreeSet;

public class TreeSetDemo2 {
    public static void main(String[] args) {
        /*
        向TreeSet添加类,必须实现Comparable接口,支持比较大小进行排序
         */
        Car car1 = new Car(101, "宝马1");
        Car car2 = new Car(102, "宝马2");
        Car car3 = new Car(103, "宝马3");
        Car car4 = new Car(101, "宝马1");
        Car car5 = new Car(104, "宝马5");
        TreeSet<Car> ts=new TreeSet<>();
        ts.add(car1);
        ts.add(car2);
        ts.add(car3);
        ts.add(car4);
        ts.add(car5);
        System.out.println(ts);//[Car{num=101, name='宝马1'}, Car{num=102, name='宝马2'}, Car{num=103, name='宝马3'}, Car{num=104, name='宝马4'}]
    }
}


import java.util.Objects;

public class Car implements Comparable<Car>{
    private int num;
    private  String name;
    public Car(int num,String name){
        super();
        this.num=num;
        this.name=name;
    }

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Car car = (Car) o;
        return num == car.num &&
                Objects.equals(name, car.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(num, name);
    }
    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public String getName() {
        return name;
    }

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


    @Override
    public int compareTo(Car o) {
        return this.num-o.num;
    }
}
遍历方式:

增强for循环 迭代器遍历

因为set集合,元素没有索引,索引就不能使用普通的for。

3. Map

将键映射到值的对象 一个映射不能包含重复的键 每个键最多只能映射到一个值。

有三个实现类

● HashMap

元素的key值不能重复, 排列顺序是不固定的,可以存储一个 为null的键。

import java.util.Collection;
import java.util.HashMap;
import java.util.Set;

public class HashMapDemo {
    public static void main(String[] args) {
        /*
        Map  键值对形式存储数据
             键不能重复,值可以
        HashMap
             键无序,只能存储一个null键
         */
        HashMap<String,String> hm=new HashMap<>();
        hm.put("a","aa");
        hm.put("x","yy");
        hm.put("b","bb");
        hm.put("s","yy");
        hm.put("b","bbb");
        //hm.clear(); //清空hm中所有键值
        //hm.remove(); //删除指定key
        System.out.println(hm.get("a"));//aa
        System.out.println(hm.containsKey("bb"));//false //判断是否包含指定的key
        System.out.println(hm.isEmpty());//false
        System.out.println(hm.size());//4  //键值对数

        /*Collection<String> list=hm.values();
        System.out.println(list);*/
        Set<String> keyset=hm.keySet();//获取hm中所有的key
        for(String key:keyset){
            String values=hm.get(key);
            System.out.println(key+" : "+values);/*
                                                a : aa
                                                b : bbb
                                                s : yy
                                                x : yy
                                               */
        }
        System.out.println(hm);//{a=aa, b=bbb, s=yy, x=yy}


    }
}
● TreeMap

所有的元素都保持着某种固定的顺序,如果需要得到一个有序 的Map就应该使用TreeMap,key值所在类必须实现Comparable接口,重写compareTo方法。

键是红黑树结构,可以保证键的排序和唯一性。

import java.util.TreeMap;

public class TreeMapDemo {
    public static void main(String[] args) {
        /*
        键值对存储
        根据建进行排序,建的类型必须实现Comparable接口
         */
        TreeMap<String,Integer> tm=new TreeMap<>();
        tm.put("c",2);
        tm.put("b",3);
        tm.put("a",1);
        tm.put("d",4);
        tm.put("a",11);
        System.out.println(tm);//{a=11, b=3, c=2, d=4}
    }
}
● HashTable

键值对存储

底层结构和HashMap类似,但Hashtable线程安全

不能存储为null的key

import java.util.Hashtable;

public class HashtableDemo {
    public static void main(String[] args) {
       
        Hashtable<String,String> ht=new Hashtable<>();
        ht.put("a","a");
        ht.put("s","s");
        ht.put("g","g");
        ht.put("a","a");
        ht.put("b","b");
        System.out.println(ht);//{b=b, a=a, s=s, g=g}
    }
}
import java.util.Hashtable;

public class HashtableDemo {
    public static void main(String[] args) {
       
        Hashtable<String,String> ht=new Hashtable<>();
        ht.put(null,"a");
        System.out.println(ht);
/*
Exception in thread "main" java.lang.NullPointerException
    at java.util.Hashtable.put(Hashtable.java:465)
    at com.albb.javaCollection.Map.HashtableDemo.main(HashtableDemo.java:18)

*/
    }
}
for 遍历

方式1:根据键找值 • 获取所有键的集合 • 遍历键的集合,获取到每一个键 • 根据键找值 方式2:根据键值对对象找键和值 • 获取所有键值对对象的集合 • 遍历键值对对象的集合,获取到每一个键值对对象 • 根据键值对对象找键和

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class HashMapFor {
    public static void main(String[] args) {
        HashMap<String,String> hm=new HashMap<>();
        hm.put("a","1");
        hm.put("s","4");
        hm.put("b","2");
        hm.put("e","3");
        Set<String> keyset=hm.keySet();
        for(String key:keyset){
            System.out.println(hm.get(key));
                                        /*
                                        1
                                        2
                                        4
                                        3
                                        */
        }
        /*
        方法2:遍历时,将key-value封装到一个个Entry对象中,包含了key和value

         */
        Set<Map.Entry<String,String>> entryset=hm.entrySet();
        for(Map.Entry<String,String> entry:entryset){
            System.out.println(entry.getKey()+":"+entry.getValue());
                                /*
                                                    a:1
                                                    b:2
                                                    s:4
                                                    e:3


                                  */
        }

    }
}

4.Collections 类

● Collections是集合类的工具类,与数组的工具类Arrays类似.

它里面的方法有很多,如:

addAll(Collection<? super T> c, T... elements);

该方法的第二位参数以下代码中详解

binarySearch(List<? extends Comparable<? super T>> l ist, T key)

sort(List<T> l ist)

sort(List<T> l ist, Comparator<? super T> c) 后面讲

swap(List<?> l ist, int i, int j)

copy(List<? super T> dest, List<? extends T> src) ; 注意 dest size需大于等于src.size

emptyList() 返回为空的集合,不能添加数据

fill(List<? super T> l ist, T obj)

max(Col lection<? extends T> col l)

min(Col lection<? extends T> col l)

replaceAl l(List<T> l ist, T oldVal, T newVal)

reverse(List<?> l ist)

shuffle(List<?> l ist) 随机排序

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class CollectionsDemo {
    public static void main(String[] args) {
        /*
        Collection 接口  是单列集合的顶级接口
        Collections类  提供关于集合操作的方法类似于Arrays类
         */
        ArrayList<String> a=new ArrayList<>();
        a.add("a");
        a.add("d");
        a.add("c");
        a.add("b");
        /*//Collections.addAll(a,"1","2","3");将指定元素添加到原数组中
        System.out.println(Collections.binarySearch(a,"d"));
        Collections.sort(a);
        Collections.swap(a,0,3);
        Collections.reverse(a);
        */
        ArrayList<String> b=new ArrayList<>();
        b.add("1");
        b.add("2");
        b.add("3");
        b.add("4");
        b.add("5");
        Collections.copy(b,a);//将a复制到b中,b的size()必须>=a的size()
        System.out.println(b);
        /*
        List emptyList=Collections.emptyList();
        返回一个空集合(内部类),不能使用,避免出现空指针
         */
        //Collections.fill(a,"0");
        Collections.shuffle(a);//随机调整元素位置
        System.out.println(a);
        System.out.println(Collections.max(a));
        System.out.println(Collections.min(a));
        test(1,2,3);
    }

        /*
        int...a  可变长度参数,本质是一个数组
        在一个参数列表中,只能有一个可变长度的参数,且只能放在参数列表的最后一位
         */
    public static void test(int b,int...a){
        System.out.println(Arrays.toString(a));// [2,3]
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小谭同学ha

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

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

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

打赏作者

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

抵扣说明:

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

余额充值