IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java集合(ListSetMapCollections) -> 正文阅读

[Java知识库]Java集合(ListSetMapCollections)

Java集合框架

目录

  1. 集合的概念
  2. Collection接口
  3. Collection父接口
  4. List接口
  5. List实现类在这里插入代码片
  6. 泛型和工具类
  7. Set接口和实现类
  8. Map接口与实现类
  9. Collections工具类

1、什么是集合

1.1集合的概念

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

1.2集合和数组的区别

  • 1 数组的长度固定,集合长度不固定
  • 2 数组可以存储基本类型和引用类型,集合只能存储引用类型

2、 Collection体系结构:

请添加图片描述

3、 Collection父接口

  • 特点:代表一组应以类型的对象,无序、无下标、不能重复
  • 方法
    • boolean add (0bject obj) //添加一个对象。
    • boolean addAl1 (Collection c) //将一个集合中的所有对象添加到此集合中。
    • void clear() //清空此集合中的所有对象。
    • boolean contains (Object o) //检查此集合中是否包含0对象
    • boolean equals (object o) //比较此集合是否与指定对象相等。
    • boolean isEmpty () //判断此集合是否为空
    • boolean remove (0bject o) //在此集合中移除0对象
    • int size() //返回此集合中的元素个数。
    • Object[] toArray() //将此集合转换成数组。
    public static void main(String[] args) {
        //创建集合
        Collection collection = new ArrayList();
        //1 添加元素
        collection.add("西瓜");
        collection.add("苹果");
        collection.add("梨子");
        System.out.println(collection.size());//打印集合长度
        System.out.println(collection);
        //2 删除元素
//        collection.remove("苹果");
        //3 遍历元素
        //3.1 增强for
        for (Object o : collection) {
            System.out.println(o);
        }
        System.out.println("---------------------");
        //3.2 使用迭代器:专门用来遍历集合的方法(hasNext,next,remove)
        /*
        hasNext   有没有下一个元素
        next        获取下一个元素
        remove    删除当前元素
         */
        Iterator it =  collection.iterator();
        while (it.hasNext()){
            String s = (String) it.next();
            System.out.println(s);
//            collection.remove(s);
            //.ConcurrentModificationException 并发修改异常,迭代器中不能用Collection修改
//            it.remove();//可以使用迭代器的方法删除
        }
        //4 判断
        System.out.println(collection.contains("西瓜"));//判断有没有元素西瓜
        System.out.println(collection.isEmpty());//判断是否为空
    }

4、List子接口

特点:有序、有下标、元素可以重复

  • 有序集合(也称为序列 )。 该界面的用户可以精确控制列表中每个元素的插入位置。 用户可以通过整数索引(列表中的位置)访问元素,并搜索列表中的元素。

方法:

  • void add (int index, Object o) //在index位置插入对象0。
  • boolean addAll (int index, Collection c) //将一个集合中的元素添加到此集合中的index位置。
  • Object get (int index) //返回集合中指定位置的元素。
  • List sublList (int fromIndex, int toIndex) //返回fromlndex和toIndex之间的集合元素。
    public static void main(String[] args) {
        //创建集合对象
        List list = new ArrayList();
        //1 添加元素
        list.add("小米");
        list.add(0,"华为");//在第0处添加
        list.add("水果");
        System.out.println(list.toString());//[华为, 小米, 水果]
        //2 删除元素
        list.remove(2);
        System.out.println(list.toString());//[华为, 小米]
        //3 遍历
        //3.1 for
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i));//华为小米
        }
        //3.2增强for
        for (Object o : list) {
            System.out.print(o);//华为小米
        }
        System.out.println("_______________");
        //3.3迭代器
        Iterator it = list.iterator();
        while (it.hasNext()){
            System.out.print(it.next());//华为小米
        }
        //3.4 listIterator列表迭代器,比Iterator强大,可以前后遍历,修改元素
        ListIterator lt = list.listIterator();
        while (lt.hasNext()){
            System.out.println(lt.nextIndex()+":"+lt.next());//0:华为1:小米
        }
        //从后往前
        while (lt.hasPrevious()){
            System.out.println(lt.previousIndex()+":"+lt.previous());//1:小米0:华为
        }
        //4 判断
        System.out.println(list.contains("华为"));//true
        System.out.println(list.isEmpty());//true
        //5 获取位置
        System.out.println(list.indexOf("华为"));//0
    }

4.1、数字及subLIst

    public static void main(String[] args) {
        List list = new ArrayList();
        //1 添加数字(自动装箱)Integer包装类
        list.add(20);
        list.add(30);
        list.add(40);
        list.add(50);
        list.add(60);
        System.out.println(list.toString());
        //删除
//        list.remove(0);
//        list.remove((Object) 20);
//        list.remove((Integer)20);
//        list.remove(new Integer(20));//数字
        System.out.println(list.toString());
        //subList 含头不含尾
        List sublist = list.subList(1,3);
        System.out.println(sublist.toString());//[30, 40]
    }

5、List实现类

  • ArrayList(重点)
    • 数组结构实现,查询快、增删慢
    • jdk1.2版本,运行效率快、线程不安全
  • Vector
    • 数组结构实现,查询快、增删慢
    • jdk1.0版本,运行慢,线程安全
  • LinkedList(常用)
    • 链表结构实现,增删快,查询慢
    • 链表首先有个head元素,添加元素,第一个就指向第二个元素以此类推

5.1、ArrayList(重点)

  • 数组结构实现,查询快、增删慢
  • 没有向集合中添加元素时,容量为0
  • //数组容量超过10以后再添加元素,就扩容到原来的1,5倍,
    • int newCapacity = oldCapacity + (oldCapacity >> 1);
例子
    public static void main(String[] args) {
        Student s1 = new Student("张三",22);
        Student s2 = new Student("李四",22);
        Student s3 = new Student("麻子",22);
        //创建集合
        ArrayList arr = new ArrayList<>();
        //1 添加
        arr.add(s1);
        arr.add(s2);
        arr.add(s3);
        System.out.println(arr.toString());
        System.out.println("_____________");
        //2 删除
//        arr.remove(s1);
        System.out.println(arr.toString());
        System.out.println("_____________");
        //3 遍历
        //迭代器
        Iterator it = arr.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }
        System.out.println("_____________");
        //列表迭代器
        ListIterator lit =  arr.listIterator();
        while (lit.hasNext()){
            System.out.println(lit.next());
        }
        System.out.println(lit.nextIndex());
        System.out.println("_____________");
        System.out.println(lit.previousIndex());
        while (lit.hasPrevious()){
            System.out.println(lit.previous());
        }
    }
ArrayList源码
/*
	源码:
	默认容量大小	 DEFAULT_CAPACITY = 10 
	空数组  		EMPTY_ELEMENTDATA = {} 
	空数组			DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}  
	存放元素的数组	 elementData			
	元素个数		size				
*/
	//构造方法
	public ArrayList() {
        //没有向集合中添加元素时,容量为0
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;//空数组
    }
	//添加元素 add
	public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
	//add方法里的ensureCapacityInternal()
	//transient Object[] elementData;
    private void ensureCapacityInternal(int minCapacity) {
        //						10
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }
	//ensureCapacityInternal方法里的alculateCapacity
    private static int calculateCapacity(Object[] elementData, int minCapacity) {
        //elementData
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            //Math.max()取最大值,(a >= b) ? a : b
            //				10			size+1    =1
            return Math.max(DEFAULT_CAPACITY, minCapacity);//这里返回10
        }
        return minCapacity;
    }	
	//ensureCapacityInternal方法里的ensureExplicitCapacity
    private void ensureExplicitCapacity(int minCapacity) {
        //默认为0
        modCount++;//1

        // overflow-conscious code
        //	10 -   0
        if (minCapacity - elementData.length > 0)
            //		10
            grow(minCapacity);
    }
	//ensureExplicitCapacity方法里的grow,,核心
	//					10
	private void grow(int minCapacity) {
        // overflow-conscious code
        //    0
        int oldCapacity = elementData.length;
        //		0			0					0
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        //	0				10
        if (newCapacity - minCapacity < 0)
        //    	10
            newCapacity = minCapacity;
        //	10			( Integer.MAX_VALUE - 8):很大
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        //空							空			10
        elementData = Arrays.copyOf(elementData, newCapacity);
        //创建一个容量为10的数组
    }
	//最后		0	  传进来的元素
	elementData[size++] = e;
	//添加元素到数组
	//数组容量超过10以后再添加元素,就扩容到原来的1,5倍,
	int newCapacity = oldCapacity + (oldCapacity >> 1);

5.2、Vector集合(不常用)

  • Vector类实现了可扩展的对象数组。 像数组一样,它包含可以使用整数索引访问的组件。 但是, Vector的大小可以根据需要增长或缩小,以适应在创建Vector之后添加和删除项目。
    public static void main(String[] args) {
        //创建集合
        Vector vt = new Vector<>();
        //1 添加元素
        vt.add("苹果");
        vt.add("草莓");
        vt.add("西瓜");
        System.out.println(vt.size());//3
        //2 删除,remove
        //3 遍历
       //for,增强for
        //jdk1.2之前,使用枚举器
        Enumeration en = vt.elements();
        while (en.hasMoreElements()){
            System.out.println(en.nextElement());
        }
        //4判断
        System.out.println(vt.contains("西瓜"));
        System.out.println(vt.isEmpty());
        //5 其他方法
        vt.firstElement();
        vt.lastElement();
        vt.elements();
    }

5.3、LinkedList

LinkedList(常用)

  • 链表结构实现,增删快,查询慢,双向链表
  • 链表首先有个head元素,添加元素,第一个就指向第二个元素以此类推
常用方法
    public static void main(String[] args) {
        Student s1 = new Student("张三",22);
        Student s2 = new Student("李四",22);
        Student s3 = new Student("麻子",22);
        //创建元素
        LinkedList linkedList = new LinkedList<>();
        //1 添加元素
        linkedList.add(s1);
        linkedList.add(s3);
        linkedList.add(s2);
        System.out.println(linkedList.toString());
        //2 删除
//        linkedList.remove(s1);
        //3 遍历
        //for
//        for (int i = 0; i < linkedList.size(); i++) {
//            System.out.println(linkedList.get(i));
//        }
        //增强for
//        for (Object o : linkedList) {
//            System.out.println(o);
//        }
        //迭代器
//        Iterator it = linkedList.iterator();
//        while (it.hasNext()){
//            System.out.println(it.next());
//        }
        //列表迭代器
        ListIterator lt = linkedList.listIterator();
        while (lt.hasNext()){
            System.out.println(lt.next().toString());
        }
        //4 判断
        System.out.println(linkedList.contains(s1));
        System.out.println(linkedList.isEmpty());
        //5 获取
        System.out.println(linkedList.indexOf(s1));//获取下标
    }
LinkedList 源码
  • size = 0
  • first 头 last 尾
  • 前一个指向后一个,后一个指向前一个
//构造方法空
    public LinkedList() {
    }
//add方法
    public boolean add(E e) {
        linkLast(e);
        return true;
    }
//linkLast(e);
    void linkLast(E e) {
        //				 null
        final Node<E> l = last;
        //								null 元素 
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }
//Node<E>
    private static class Node<E> {
        //item当前元素
        E item;
        //下一个节点
        Node<E> next;
        //前一个节点
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

5.4 ArrayList和LinkedList的区别

请添加图片描述

  • LinkedList
    • 查询慢:需要从头或从尾一个个找
    • 删除快:删除一个元素,只需要改变指向关系就可以了

5.5、小问题

列表迭代器ListIterator

  • nextIndex()默认是0,previousIndex() : nextIndex()-1 = -1
  • 直接逆遍历需要先把遍历一次,让nextIndex()到最后一位
/*
有三个学生,Student{name='张三', age=22}
		  Student{name='李四', age=22}
		  Student{name='麻子', age=22}
*/
        ListIterator lit =  arr.listIterator();
		//正向遍历
        while (lit.hasNext()){
            System.out.println(lit.next());
        }
        System.out.println(lit.nextIndex());//3
        System.out.println(lit.previousIndex());//2
        while (lit.hasPrevious()){
            System.out.println(lit.previous());
        }
		//注释掉正向遍历后
//        while (lit.hasNext()){
//            System.out.println(lit.next());
//        }
        System.out.println(lit.nextIndex());//0
        System.out.println("_____________");
        System.out.println(lit.previousIndex());//-1
        while (lit.hasPrevious()){//就不能遍历了
            System.out.println(lit.previous());
		}
		//可以在逆向遍历之前正向遍历一遍解决

6、泛型

  • Java泛型是JDK1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递。
  • 常见形式有泛型类、泛型接口、泛型方法。
  • 语法:
    • .<T,…> T称为类型占位符,表示一种引用类型。
  • 好处:
    • (1)提高代码的重用性:比如传递时可以传递任意类型的参数
    • (2)防止类型转换异常,提高代码的安全性

6.1、泛型类

  • 语法,类名
  • T是类型占位符,表示一种引用类型,如果编写多个使用逗号隔开
  • 泛型只能使用引用类型
  • 不同泛型类型对象之间不能相互赋值
/**
 * 泛型类
 * 语法,类名<T>
 *  T是类型占位符,表示一种引用类型,如果编写多个使用逗号隔开
 */
public class MyGeneric<T> {
    //使用泛型T
    //1 创建变量
    T t;
    //2 泛型作为方法的参数
    public void show(T t){
        System.out.println(t);
    }
    //3泛型的方法的返回值

    public T getT() {
        return t;
    }
}
	public static void main(String[] args) {
        //使用泛型类创建变量
        //注意,1 泛型只能使用引用类型,2 不同泛型类型对象之间不能相互赋值
        MyGeneric<String> myGeneric = new MyGeneric<String>();
        myGeneric.t = "hello";
        myGeneric.show("大家好");//大家好
        String str = myGeneric.getT();
        System.out.println(str);//hello
        MyGeneric<Integer> myGeneric1 = new MyGeneric<Integer>();
        myGeneric1.t = 100;
        myGeneric1.show(200);//200
        Integer integer = myGeneric1.getT();
        System.out.println(integer);//100
    }

6.2、泛型接口

  • 定义泛型接口,接口名
  • 注意:不能用泛型创建常量
  • 实现类
    • 1:可以在实现类上泛型直接指定类型,方法使用对应类型
    • 2:实现类泛型不指定类型,使用的时候再指定

例子:

/**
 * 泛型接口
 * 语法:接口名<T>
 * 注意:不能用泛型创建常量
 */
public interface MyInterface<T> {
    String name = "张三";
    T server(T t);
}
//实现类1 指定类型<String>
public class MyInterfaceImpl implements MyInterface<String> {
    @Override
    public String server(String t) {
        System.out.println(t);
        return t;
    }
}
//实现类2 不指定类型
public class MyInterfaceImpl2<T> implements MyInterface<T> {
    @Override
    public T server(T t) {
        System.out.println(t);
        return t;
    }
}
//测试
    public static void main(String[] args) {
        MyInterfaceImpl impl1 = new MyInterfaceImpl();
        impl1.server("ttttttttttttt");//tttttttttt
        MyInterfaceImpl2<Integer> impl2 = new MyInterfaceImpl2<>();
        impl2.server(2020);//2020
    }

6.3、泛型方法

  • 语法,方法返回值类型前加:public void show(){}、
  • 传递的类型是由传递的值决定
//泛型方法
    public <T> T show(T t){
        System.out.println("泛型方法"+t);
        return t;
    }
//调用
        //泛型方法
        MyGenericMethod mg = new MyGenericMethod();
		//传递的类型是由传递的值决定
        mg.show(222);
        mg.show("行啊");

6.4、泛型集合

概念:

  • 参数化类型、类型安全的集合,强制集合元素的类型必须一致

特点:

  • 编译时即可检查,而非运行时抛出异常
  • 访问时,不需要类型转换(拆箱)
  • 不同泛型之间引用不能相互赋值,泛型不存在多态
    public static void main(String[] args) {
        ArrayList<String> arrayList = new ArrayList();
        arrayList.add("aaa");
        arrayList.add("bbb");
        for (String s : arrayList) {
            String ss = s;
            System.out.println(ss);
        }
        Student s1 = new Student("aaa",11);
        Student s2 = new Student("bbb",22);
        ArrayList<Student> arrayList1 = new ArrayList<>();
        arrayList1.add(s1);
        arrayList1.add(s2);
        Iterator<Student> it = arrayList1.iterator();
        while (it.hasNext()){
            //添加泛型指定Student类型后,获取的也是Student类型
            Student st = it.next();
            System.out.println(st);
        }
    }

7、Set子接口

特点:

  • 无序、无下标、元素不可以重复

方法:

  • 全部继承Collection的方法
    public static void main(String[] args) {
        //创建集合
        Set<String> set = new HashSet<>();
        //1 添加数据
        set.add("苹果");
        set.add("西瓜");
        set.add("香蕉");
        System.out.println(set.toString());//[苹果, 香蕉, 西瓜]
        //2 删除
//        set.remove("香蕉");
        //3 遍历
        //增强for
        for (String s : set) {
            System.out.println(s);
        }
        //迭代器
        Iterator<String> it  = set.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }
    }

7.1、Set实现类(HashSet)

  • 基于HashCode计算元素存放位置

  • 当存入元素的哈希码相同时,会调用equals进行确认,如果结果为true,,则拒绝后者存入

  • 存储过程

    • 根据hashcode计算保存位置,如果位置为空,直接保存,如果不为空执行第二步
    • 执行equals,如果equals为true,认为是重复,否则形成链表
    public static void main(String[] args) {
        //创建集合
        HashSet<Person> hashSet = new HashSet<>();
        //添加数据
        Person s1 = new Person("张三",11);
        Person s2 = new Person("麻子",22);
        Person s3 = new Person("蓝色",33);
        hashSet.add(s1);
        hashSet.add(s2);
        hashSet.add(s3);
        hashSet.add(new Person("张三",11));//是不同对象可以添加
        //重写hashcode,和equals后相同元素就不能添加了
        System.out.println(hashSet);
        //删除
//        hashSet.remove(s1);
        //重写hashcode,和equals后相同元素就不能删除了
        hashSet.remove(new Person("张三",11));
    }

7.2、TreeSet

特点:

  • 基于排序实现元素不重复
  • 实现了SortedSet接口,对集合元素自动排序
  • 元素对象的类型必须实现Comparable接口,指定排序规则
  • 通过CompareTo方法确定是否为重复元素
	@Override
    //Person类:实现Comparable接口,重新compareTo()方法
    //先比姓名再比年龄
    public int compareTo(Person o) {
        int n1 = this.getName().compareTo(o.getName());
        int n2 = this.age-o.getAge();
        return n1==0?n2:n1;
    }

/**
 * TreeSet
 * 存储结构:红黑树
 *
 */
public class Demo2 {
    public static void main(String[] args) {
        TreeSet<Person> person = new TreeSet<>();
        //1 添加元素
        Person p1 = new Person("xyz",18);
        Person p2 = new Person("aaa",33);
        Person p3 = new Person("ddd",22);
        Person p4 = new Person("ddd",20);
        person.add(p1);
        person.add(p2);
        person.add(p3);
        person.add(p4);
        System.out.println(person);
        //2 删除元素
        person.remove(new Person("ddd",20));
        //3 遍历
        //增强for
        //迭代器
    }

自定义比较规则

  • 先比年龄,再比姓名
    public static void main(String[] args) {
        //内部类
        TreeSet<Person> ts = new TreeSet<>(new Comparator<Person>() {
            @Override
            //先比年龄,再比姓名
            public int compare(Person o1, Person o2) {
                int n1 = o1.getAge()-o2.getAge();
                int n2 = o1.getName().compareTo(o2.getName());
                return n1 == 0 ? n2:n1 ;
            }
        });
        Person p1 = new Person("xyz",18);
        Person p2 = new Person("aaa",33);
        Person p3 = new Person("ddd",22);
        Person p4 = new Person("ddd",20);
        ts.add(p1);
        ts.add(p2);
        ts.add(p3);
        ts.add(p4);
        System.out.println(ts);
    }
  • 字符串按长度进行排序
    public static void main(String[] args) {
        TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {
            @Override
            //长度从长往短排
            public int compare(String o1, String o2) {
                int n1 = o2.length()-o1.length();
                int n2 = o1.compareTo(o2);
                return n1==0 ? n2:n1;
            }
        });
        ts.add("sidfhkajlsdhfj");
        ts.add("aaas");
        ts.add("bbb");
        ts.add("cccds");
        ts.add("caaas");
        System.out.println(ts);
        //[sidfhkajlsdhfj, caaas, cccds, aaas, bbb]
    }

8、Map集合

请添加图片描述

8.1、Map父接口

特点:

  • 存储一对数据(Key-Value),无序、无下标,键不可重复,值可以重复

方法:

  • V put (K key, V value) //将对象存入到集合中,关联键值。key重复则覆盖原值。
  • Object get (object key) //根据键获取对应的值。
  • KeySet //返回所有key。
  • Collection values () //返回包含所有值的Collection集合。
  • Set<Map. Entry<K, V>> //键值匹配的Set集合。
  • entrySet() 返回此映射中包含的映射关系的Set视图。
    public static void main(String[] args) {
        Map<String,String> map = new HashMap<>();
        //1 添加
        map.put("pg","苹果");
        map.put("xg","西瓜");
        map.put("xj","香蕉");
        System.out.println(map.size()+":"+map);
        //2 删除
//        map.remove("xg");
//        System.out.println(map.size()+":"+map);
        //3 遍历
        // 1 keySet
//        Set<String> s =  map.keySet();
        for (String s1 : map.keySet()) {
            System.out.println(s1+":"+map.get(s1));
        }
        // 2 使用entrySet()遍历
//        Set<Map.Entry<String, String>> entries = map.entrySet();
//        for (Map.Entry<String, String> entry : entries) {
        for (Map.Entry<String, String> entry : map.entrySet()) {
            System.out.println(entry.getKey()+":"+entry.getValue());
        }
        //4 判断
        System.out.println(map.containsValue("西瓜"));
        System.out.println(map.isEmpty());
    }

8.1、HashMap*

  • JDK1.2支持,线程不安全,运行效率快;允许使用null作为key或Value

  • 构造方法

    • HashMap() 构造一个空的 HashMap ,默认初始容量(16)和默认负载系数(0.75)。

    • HashMap(int initialCapacity) 构造一个空的 HashMap具有指定的初始容量和默认负载因子(0.75)。

    • HashMap(int initialCapacity, float loadFactor) 构造一个空的 HashMap具有指定的初始容量和负载因子。

    • HashMap(Map<? extends K,? extends V> m) 构造一个新的 HashMap与指定的相同的映射 Map

基于哈希表的实现的Map接口。 此实现提供了所有可选的地图操作,并允许null的值和null键。 ( HashMap类大致相当于Hashtable ,除了它是不同步的,并允许null)。这个类不能保证地图的顺序; 特别是,它不能保证订单在一段时间内保持不变。

    public static void main(String[] args) {
        HashMap<Student,String> hm = new HashMap<>();
        //添加元素
        Student s1 = new Student("孙悟空",100);
        Student s2 = new Student("猪八盖",101);
        Student s3 = new Student("沙僧",102);
        hm.put(s1,"贵阳");
        hm.put(s2,"金阳");
        hm.put(s3,"火车站");
        hm.put(new Student("沙僧",102),"北站");//hashcode不同可以添加,可以通过重新hashcode和equals
        System.out.println(hm.size()+":"+hm);
        //2 删除 remove
        //3 遍历
        // KeySet
        for (Student student : hm.keySet()) {
            System.out.println(student+":"+hm.get(student));
        }
        //entrySet
        for (Map.Entry<Student, String> studentStringEntry : hm.entrySet()) {
            System.out.println(studentStringEntry.getKey()+":"+studentStringEntry.getValue());
        }
    }

HashMap小结:

  • 刚创建集合时集合的长度为0,(节省空间)
  • (put)添加数据时集合长度调整为16(0-15)
  • 当数据个数达到阈值(16*0.75)12时,扩容为原来的两倍,32(16的二倍)
  • jdk1.8当每个链表长度大于8,并且元素个数大于等于64时,会调整为红黑树,日的提高执行效率
  • jdk1.8当链表长度小于6时,调整成链表
  • jdk 1.8以前,链表时头插入, jdk1.8以后时是尾插入

HashMap和HashSet

  • HashSet实际上使用的是HashMap的Key

8.2、Hashtable和Properties

  • JDK1.0版本,线程安全,运行效率慢,键值不允许为null
  • 子类:Properties
    • 要求键值都是String,通常用于配置文件的读取

8.3、TreeMap

  • 实现了sort
  • 结构:红黑树
    public static void main(String[] args) {
        TreeMap<Student, String> tm = new TreeMap<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                int n1 = o1.getStuNo()-o2.getStuNo();
                return n1;
            }
        });
        //1.添加对象
        Student s1 = new Student("孙悟空",100);
        Student s2 = new Student("猪八盖",101);
        Student s3 = new Student("沙僧",102);
        tm.put(s1,"北京");
        tm.put(s2,"上海");
        tm.put(s3,"深圳");
        System.out.println(tm.size()+":"+tm);
        tm.put(new Student("沙僧1",102),"南京");//替换了value
        System.out.println(tm.size()+":"+tm);
        //2 删除,remove
        //3 遍历
        //keySet
        for (Student student : tm.keySet()) {
            System.out.println(student+":"+tm.get(student));
        }
        //entrySet
        for (Map.Entry<Student, String> entry : tm.entrySet()) {
            System.out.println(entry.getKey()+":"+entry.getValue());
        }
        //4 判断,containsKey,IsEntry
    }

TreeSet 和TreeMap

  • TreeSet使用的TreeMap的key

9、Collections工具类

概念:

  • 集合工具类,定义了除了存取以外的集合常用方法。
  • 方法:
    • public static void reverse(List<?> list) //反转集合中元素的顺序
    • public static void shuffle(List<?> list) //随机重置集合元素的顺序
    • public static void sort (List list) //升序排序(元素类型必须实现Comparable接口)
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(22);
        list.add(5);
        list.add(2);
        list.add(44);
        list.add(11);
        //sort 排序 默认升序
        Collections.sort(list);
        System.out.println(list);//[2, 5, 11, 22, 44]
        //binarySearch 二分查找(先排序) ,有就返回下标,没有返回负数
        int i = Collections.binarySearch(list,444);//-6
        System.out.println(i);
        //copy复制
        List<Integer> list1 = new ArrayList<>();
        //copy方法复制的对象没有长度会报异常IndexOutOfBoundsException
        for (int j = 0; j < list.size(); j++) {
            //先赋值0
            list1.add(0);
        }
        Collections.copy(list1,list);
        System.out.println(list1);//[2, 5, 11, 22, 44]
        //reverse反转
        Collections.reverse(list);
        System.out.println(list);//[44, 22, 11, 5, 2]
        //shuffle 打乱,每次都不一样
        Collections.shuffle(list);
        System.out.println(list);//[22, 2, 5, 11, 44]

    }

数组集合转换

        //list转成数组,长度和list长度一样
        Integer[] it = list.toArray(new Integer[0]);
        System.out.println(it.length+":"+ Arrays.toString(it));//5:[11, 44, 5, 2, 22]
        //把数组转成集合  ,创建的时候固定了长度,不能添加或删除,可以修改
        String[] names  = {"aaa","bbb","ddd","FFF"};
        List<String> list2 = Arrays.asList(names);
        //出现异常UnsupportedOperationException
//        list2.add("sss");
        System.out.println(list2);//[aaa, bbb, ddd, FFF]
        //基本类型数组转集合时需要写包装类型
        Integer[] nums = {111,222,33,44,55};
        List<Integer> integers = Arrays.asList(nums);
        System.out.println(integers);//[111, 222, 33, 44, 55]

小问题

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-11-27 09:46:50  更:2021-11-27 09:48:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:11:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码