这可能是你见过最全的集合

Collection集合特点

  • List系列集合:添加的元素是有序的,可重复,有索引的。
    • ArrayList、LinekdList:有序,可重复,有索引
  • Set系列集合:添加的元素是无序,不重复,无索引。
    • HashSet:无序、不重复==、无索引;
    • LinkedHashSet:有序、不重复、无索引。
    • TreeSet:按照大小默认升序排序,不重复,无索引

注意:集合和泛型都只能支持引用数据类型,不支持基本数据类型,所以集合中存储的元素都认为是对象

Collection API

package com.djn.day1;

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

public class CollectionApi {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<String>();
        list.add("java");
        list.add("java");
        list.add("mysql");
        list.add("html");
        list.add("css");
        System.out.println("list.add的返回值boolean:"+list.add("css"));  //返回值为true;
        System.out.println("判断字符是否为空---->"+list.isEmpty());
        System.out.println("获取集合的长度---->"+list.size());
        System.out.println("判断集合是否包含某个元素:---->"+list.contains("java"));
        System.out.println("从集合中删除一个元素:---->"+list.remove("java"));
        //将集合转换成数组,
        Object[] arrs = list.toArray();
        System.out.println("数组---->"+Arrays.toString(arrs));
        System.out.println("----------------拓展-----------------");
        Collection<String> c1 = new ArrayList<String>();
        c1.add("陈奕迅");
        c1.add("韩红");
        Collection<String> c2 = new ArrayList<String>();
        c2.add("呵呵");
        c2.add("哈哈");
        //addAll把c2中的集合全部复制c1中去  ,
        c1.addAll(c2);
        System.out.println(c1);
        System.out.println(c2);
        
    }

}

Collection遍历方式

Iterator迭代器遍历collection集合

boolean hashNext():获取当前位置是否有元素存在,存在则返回true;

next():获取当前位置的元素,并同时将迭代器对象移向下一个位置,注意防止取出越界

Collection<String> list = new ArrayList<String>();
  list.add("java");
  list.add("mysql");
  list.add("html");
  list.add("css");
//        [java, java, mysql, html, css]
  System.out.println(list);
  System.out.println("-----------------------------");
//1、得到当前集合的迭代器对象
  Iterator<String> it = list.iterator();
  String ele = it.next();
  System.out.println(ele);
  System.out.println(it.next());
  System.out.println(it.next());
  System.out.println(it.next());
 // System.out.println(it.next());  //java.util.NoSuchElementException 越界
	   // while循环
//2、定义while循环遍历  
		Iterator<String> it = list.iterator();	
  while (it.hasNext()){				//hasNext()判断是否有下一个元素
      String ele = it.next();			//next方法会迭代器对象移动到下一个位置
      System.out.println(ele);
  }


for each遍历
  • 增强for循环:既可以遍历集合也可以遍历数组
  • 他是JDK5之后出现的,其内部原理是一个Iterator迭代器,集合遍历相当于是迭代器的简化写法。
  • 实现Iterable接口的才可以使用迭代器和for each,Collection接口已经实现了Iterable接口
//格式
		for(元素数据类型 变量名:数组或者Collection集合){
          //在此处使用变量即可,该变量就是元素
      }
//栗子
		Collection<String> list = new  ArrayList<>();
		...
      for(String ele : list){
          System.out.println(ele);
      }
Collection结合Lambda遍历的API

栗子:

package com.djn.day1;

import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;

public class LambdaIterator {
    public static void main(String[] args) {
        Collection<String> list = new ArrayList<String>();
        list.add("java");list.add("mysql");
        list.add("html");list.add("css");
        //不简化。。。。。
        list.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
        //Lambda表达式。。。。。。。。。。。。
        list.forEach(s -> System.out.println(s) );
        //或者。。。。。。。完全看不懂
        list.forEach(System.out::println );
    }
}

List集合

  • List集合因为支持索引,所以多了很多索引操作的独特api,其他collection的功能也都继承了,
  • void add(int index,e element):在此集合中的指定位置插入指定的元素
  • E remove(int index,E element):修改指定索引处的元素,返回被修改的元素
  • E get(int,index) 返回指定索引的元素
List<String> list = new ArrayList<String>();
      list.add("java");
      list.add("html");
      list.add("mysql");
      list.add("linux");
      //在某个索引位置添加元素
      list.add(2,"python");
      System.out.println(list);
      //根据索引删除元素,返回被删除的元素
      System.out.println(list.remove(2));
		//根据索引获得元素
      System.out.println(list.get(2));
		//根据索引修改元素,返回值为被修改的元素
		System.out.println(list.set(2,"董俊楠"));

List的实现类的底层原理

ArrayList
  • ArrayList底层是基于数组实现的,根据查询元素快,增删相对慢
  • LinkedList底层基于双链表表现得,查询元素慢,增删首位元素是非常快的
		System.out.println("--------------简单for循环-----------------");
        for (int i = 0; i <list.size() ; i++) {
            System.out.println(list.get(i));
        }
        System.out.println("---------------Iterator迭代器----------------");
        //迭代器
        Iterator<String> it =list.iterator();
        while(it.hasNext()){
            String ele = it.next();
            System.out.println(ele);
        }
        System.out.println("--------------增强for循环-----------------");
        for (String s : list) {
            System.out.println(s);
        }
  • ArrayList底层是基于数组实现的:根据索引定位元素快,增删元素需要做移位操作。
  • 第一次创建层创建一个默认长度为 10的数组
LinkedList

addFirst()----->push():向集合首位加入 ,入栈

removeFirst()------>pop():移除第一个,弹栈

addLast()------>入队

removeFirst()----->出队

循环遍历删除元素

package com.djn.day2;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Test {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("java");
        list.add("java");
        list.add("html");
        list.add("mysql");
        list.add("linux");
        //删除所有的java
        //1、迭代器删除
        Iterator<String> it = list.iterator();
        while (it.hasNext()){
            String ele = it.next();
            if (ele.equals("java")){
                //使用迭代器删除当前所在元素,并且不会后移,不会漏掉元素
                it.remove();
            }
        }
        System.out.println(list);

        //2、for循环倒着删除
        for (int i = list.size()-1; i >=0 ; i--) {
            String ele = list.get(i);
            if (ele.equals("java")){
                list.remove("java");
            }
        }
        //3、for循环删除
        for (int i = 0; i<list.size();i++) {
            String ele = list.get(i);
            if (ele.equals("java")){
                list.remove("java");
            }
            i--;  //删除后让索引后退,防止漏删
        }
    }
}

Set系列

set系列集合特点

  • 无序:存放顺序不一致
  • 不重复:可以去除重复
  • 无索引:没有带索引的方法,所以不能使用普通for循环遍历,也不能通过索引获取元素

Set集合实现类特点

  • HashSet:无序,不重复,无索引
  • LinkedHashSet:有序、不重复,无索引
  • TreeSet:排序、不重复、无索引

HashSet

HashSet底层原理

  • HashSet集合底层采取哈希表存储的数据
  • 哈希表是一种对于增删改查数据性能都能较好的结构

哈希表的组成

  • JDK8之前的,底层使用数组+链表组成
  • JDK8开始后,底层采取数组+链表+红黑树组成

哈希值

  • 是JDK根据对象的地址,按照某种规则算出来的int类型的数值

Object类的API

  • public int hashCode():返回对象的哈希值

对象的哈希值特点

  • 同一个对象多次调用hashCode()方法返回哈希值是相同的
  • 默认情况下,不同对象的哈希值是不同的

HsshSet1.7:数组+链表+(结合哈希算法)

  • 创建一个默认长度16的数组,数组名table
  • 根据元素的哈希值跟数组长度求余计算应存入位置(哈希算法)
  • 判断当前位置是否为null,如果是null直接存入
  • 如果位置部位null,表示有元素,则调用equals方法比较
  • 如果一样,则不存,如果不一样,则存入数组
    • JDK 7新元素占老元素位置,之现象老元素
    • JDK 8中新元素挂在老元素下面

JDK1.8版本开始HashSet原理解析

  • 底层结构:哈希表(数组、链表、红黑树的结合体
  • 当挂在元素下面的数据过多时,查询性能降低,从JDK8开始后,当链表长度超过8的时候,自动转换为红黑树。
HashSet去重复原理
  • 创建一个默认长度16的数组,数组名table
  • 根据元素的哈希值跟数组长度求余计算应存入位置(哈希算法)
  • 判断当前位置是否为null,如果是null直接存入
  • 如果位置部位null,表示有元素,则调用equals方法比较
  • 如果一样,则不存,如果不一样,则存入数组
	@Override
	//重写hashCode和equals后,值相同的对象返回的hashcode相同
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name, student.name) &&
                Objects.equals(sex, student.sex);
    }

    @Override
    public int hashCode() {

        return Objects.hash(name, age, sex);
    }

 public static void main(String[] args) {
        Set<Student> sets = new HashSet<>();
        Student s1 = new Student("aaa",12,"男");
        Student s2 = new Student("bbb",13,"女");
        Student s3 = new Student("ddd",14,"男");
        Student s4 = new Student("ddd",14,"男");
        sets.add(s1);
        sets.add(s2);
        sets.add(s3);
        sets.add(s4);
        System.out.println(s1.hashCode());		// 92624651
        System.out.println(s2.hashCode());		//93571847
        System.out.println(s3.hashCode());		//95487532
        System.out.println(s4.hashCode());		//95487532
        System.out.println(sets);	
     //[SetDemo3{name='bbb', age=13, sex='女'}, SetDemo3{name='ddd', age=14, sex='男'}, SetDemo3{name='aaa', age=12, sex='男'}]
    }

LinkedHashSet

LinkedHashSet集合概述和特点
  • 有序、不重复,无索引
  • 这里的有序指的是保证存储和取出的元素顺序一致
  • 原理:底层数据结构依然是哈希表,只是每个元素又额外的多了一个双链的机制记录存储顺序。

TreeSet

特点概述
  • 不重复、无索引、可排序
  • 可排序:按照元素的大小默认升序(有小到大)排序
  • TreeSet集合底层是基于红黑树的数据结构实现排序的,增删改查性能都较好

TreeSet集合是一定要排序的,可以将元素按照指定元素的规则进行排序

TreeSet集合默认的规则

  1. 对于数值类型:Inteher,Double,官方默认按照大小进行升序排序
  2. 对于字符串类型:默认按照首字母的编号升序排序
  3. 杜宇自定义类型如Student对象,TreeSet无法直接排序
    • 1、类实现Comparable接口,重写比较方法
    • 2、集合自定义Comparator比较器对象,重写比较规则
package com.djn.d1_set;

import java.util.Set;
import java.util.TreeSet;

/*
* 观察TreeSet对于有特性的数据如何排序
* 学会自定义类型的对象进行指定规则排序
* */
public class SetDemo5 {
    public static void main(String[] args) {
        Set<Integer> set1 = new TreeSet<>();
        set1.add(12);
        set1.add(23);
        set1.add(45);
        set1.add(98);
        System.out.println(set1);		//[12, 23, 45, 98]
        System.out.println("----------------");
        Set<String> set2 = new TreeSet<>();
        set2.add("angela");
        set2.add("mysql");
        set2.add("java");
        set2.add("php");
        set2.add("董槿兮");
        set2.add("html");
        set2.add("css");
        set2.add("About");
        System.out.println(set2);		//[About, angela, css, html, java, mysql, php, 董槿兮]
       // Exception in thread "main" java.lang.ClassCastException: com.djn.d1_set.Apple cannot be cast to java.lang.Comparable
    }
}
对象类型排序
public class Apple implements Comparable<Apple>{		//继承Comparable接口,
    private String name;
    private String color;
    private  double price;
    private int weight;		
    ......
        /*
    	* 方式一:类自定义比较规则
    * */
    @Override
    public int compareTo(Apple o) {
        return this.weight - o.weight;		//按照重量排序,但是如果重量相等则会去重		
        return this.weight - o.weight >= 0 ? 1:-1;	//如果两个相同,则认为第一个大
    }
}

//测试
	package com.djn.d1_set;

import java.util.Set;
import java.util.TreeSet;

/*
* 观察TreeSet对于有特性的数据如何排序
* 学会自定义类型的对象进行指定规则排序
* */
public class SetDemo5 {
    public static void main(String[] args) {
        Set<Apple> apples = new TreeSet<>();
        apples.add(new Apple("红富士","红色",9.9,600));
        apples.add(new Apple("青苹果","青色",15.9,300));
        apples.add(new Apple("黄苹果","黄色",5.8,100));
        apples.add(new Apple("苹果","苹果色",9.8,300));
        System.out.println(apples);       
        
        //方式2
        Set<Apple> apple = new TreeSet<>(new Comparator<Apple>() {
            @Override
            public int compare(Apple o1, Apple o2) {
                return o2.getWeight()-o1.getWeight();	//o2 - o1 为倒叙
                return Double.compare(o1.getPrice(),o2.getPrice()) >=0 ? 1 : -1;  //浮点型建议使用compare比较;
            }
        });
        //Lambda表达式简化
        //t<Apple> apple = new TreeSet<>((o1,o2) ->Double.compare(o1.getPrice(),o2.getPrice()) >=0 ? 1 : -1 );
        apple.add(new Apple("红富士","红色",9.9,600));
        apple.add(new Apple("青苹果","青色",15.9,300));
        apple.add(new Apple("黄苹果","黄色",5.8,100));
        apple.add(new Apple("苹果","苹果色",9.8,300));
        System.out.println(apple);
    }
}


总结

  • 如果希望元素可以重复,又有索引,索引查询要快?
    • 用ArrayList集合,基于数组的(用的最多)
  • 如果希望元素可以重复,又有索引,增删首操作快?
    • 用LinkedList集合,基于链表的。
  • 如果希望增删改查都快,但是元素不重复,无序、无索引
    • 用HashSet集合,基于哈希表的。
  • 如果希望增删改查都快,但是元素不重复,有序,无索引
    • 用LinkedHashSet集合,基于哈希表和双链表
  • 如要对对象进行排序
    • 用TreSet集合,基于红黑树,后续也可以使用List集合实现排序

可变参数

  • 可变参数用在形参中可以接收多个数据
  • 可变参数的格式:数据类型...参数名称
package com.djn.d1_set;

import java.util.Arrays;

public class MethodDemo {
    public static void main(String[] args) {
        sum();
        sum(10  );
        sum(20,60);

    }
    public static void sum(int...nums){
        System.out.println("元素个数" + nums.length);
        System.out.println("元素内容" + Arrays.toString(nums));
    }
}

可变参数的作用
  • 传输参数非常灵活,方便,可以不传输参数,可传一个或多个,也可以传数组
  • 可变擦拭农户在方法内部本质上就是一个数组
可变参数的注意事项:
  • 一个形参列表中可变参数只能有一个
  • 可变参数必须放在形参泪飙的最后

Collections集合工具类

Collections.addAll(list,"aaa","bbb","ccc","ddd"); 添加元素

Collections.shuffle(list); 打乱元素顺序 打乱list的顺序

Collections.sort(list1); 排序

package com.djn.d1_set;

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

public class CollectionsDemo {
    public static void main(String[] args) {
        List<Object> list = new ArrayList<>();
        Collections.addAll(list,"aaa","bbb","ccc","ddd");		//添加元素
        System.out.println(list);
        Collections.shuffle(list);			//打乱元素顺序
        System.out.println(list);
        List<Integer> list1 = new ArrayList<>();		//排序
        Collections.addAll(list,12,98,45,67);
        Collections.sort(list1);
        System.out.println(list);
    }
}

Map

map集合概述和使用
  • ​ Map集合的每个元素的格式:key=value(键值对元素)
  • Map集合也被称为键值对集合
Map集合整体格式
  • Collection集合的格式:[元素1, 元素2, 元素3, ...]
  • Map集合的完整格式:
Map集合体系特点
  • Map集合的特点都是由键决定的。
  • Map集合的键是无序,不重复的,五索引的
  • Map集合后面重复的键对应的值会覆盖前面重复键的值
  • Map集合的键值对都可以为null。
Map集合实现类特点
  • HashMap:元素按照键是无序,不重复,无索引,值不做要求(与map体系一致)
package MapTest;

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

public class MapDemo1 {
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("李宁",10);
        map.put("红星",00);
        map.put("李宁",9);
        map.put(null,null);
        System.out.println(map);	 //  {null=null, 红星=0, 李宁=9}
    }
    
 
  • LinkedHashMap:元素按照键是有序,不重复,无索引,值不做要求
  • TreeMap:元素按照键是排序,不重复,无索引的,值不做要求
Map常用方法

image-20220322164101093

package MapTest;

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

public class MapDemo1 {
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("李宁",10);
        map.put("红星",00);
        map.put("李宁",9);
        map.put(null,null);
        System.out.println(map);
        System.out.println(map.isEmpty());  //false
        Integer ln = map.get("李宁");        //返回的为value
        map.remove("红星");               //返回值被删除的值
        Integer hw = map.get("华为");        //若不存在,则返回null
        System.out.println(map.containsKey("李宁"));  //包含某个键
        System.out.println(map.containsValue(10));  //包含某个键
        Set<String> keys = map.keySet();     //获取map所有的键,set集合和map的键刚好都是无重复,[null, 红星, 李宁]
        Collection<Integer> values = map.values();		 //获取全部map的值,值是可以重复的,[null, 0, 9]
		HashMap<String, Integer> map1 = new HashMap<>();
        map1.put("董俊楠",1);
        map1.put("刘梦媛",2);
        HashMap<String, Integer> map2 = new HashMap<>();
        map2.put("董嗷嗷",3);
        map2.put("刘咩咩",4);
        map1.putAll(map2);			//把map2里的键值对拷贝到map1中一份
        System.out.println(map1);	//{董俊楠=1, 刘咩咩=4, 董嗷嗷=3, 刘梦媛=2}
        System.out.println(map2);	//{刘咩咩=4, 董嗷嗷=3}
    }
}

HashMap遍历
package MapTest;

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

public class MapBianLi {
    public static void main(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("李宁",10);
        map.put("红星",00);
        map.put("李宁",9);
        map.put("董俊楠",1);
        map.put("刘梦媛",2);
        map.put("董嗷嗷",3);
        map.put("刘咩咩",4);
        /*
        * 方法1:键找值
        * 1、先取到所有的键
        * 2、在通过遍历键获取值
        * */
        Set<String> keys = map.keySet();
        for (String key:keys) {
            Integer value = map.get(key);
            System.out.println(key+"=====>"+value);
        }
        /*
         * 方法2:将map集合转为set,
         *此方法面向对象
         * */
        Set<Map.Entry<String, Integer>> entries = map.entrySet();
        for (Map.Entry<String, Integer> entry:entries) {
            String key = entry.getKey();
            int value = entry.getValue();
            System.out.println(key+"--->"+value);
        }
         /*
         * 方法:lambda表达式
         * */
//         map.forEach(new BiConsumer<String, Integer>() {
//             @Override
//             public void accept(String key, Integer value) {
//                 System.out.println(key+"--->"+value);
//             }
//         });
        map.forEach((key,value)-> System.out.println(key+"--->"+value));
    }
}
HashMap的特点和底层原理
  • 有键决定:无序、不重复,无索引。HashMap底层是哈希表结构的
  • 以来hashCode方法和equals方法保证键的唯一
  • 如果要存储的是自定义对象,需要重写hashCode和equals方法
  • 基于哈希表,增删改查的性能都比较好

TreeMap

集合概述和特点
  • 由键决定特性:不重复。无索引、可排序
  • 可排序:按照键数据的大小默认升序(有小到大)排序。只能对键排序
  • 注意:TreeMap集合一定要排序的,可以默认排序,也可以将键按照指定的规则进行排序
  • TreeMap跟TreeSet一样,底层原理是一样的
posted on   曲如眉  阅读(68)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示