JavaSE-集合

目录

一、Collection

1.1Collection 迭代

1.2List

1.2.1ArrayList

1.2.2LinkedList

1.3Set

1.3.1HashSet

1.3.2LinkedHashSet

1.3.3TreeSet

二、Map

2.1HashMap

2.2LinkedHashMap

2.3TreeMap

三、工具类

3.1Collections

四、认识

4.1可变参数

4.2不可变集合

4.3泛型实例(补充)

参考:


集合

认识:集合是Java中存储对象数据的一种容器

特点:

  • 集合的大小是不固定的,启动后可以动态变化,类型选取也是不固定 通配符 的使用 的;

  • 集合适合做元素的增删操作;

  • 集合只能存储 引用类型数据,对于基本数据类型需要包装类

image-20240116195147553

一、Collection
  • Collection是 所有单列的集合的父类接口,定义了全部单列集合都可以继承使用的功能
  • 常用方法:
方法名称说明
public boolean add(E e)把给定的对象添加到当前几何中
public void clear()清空集合中所有元素
public boolean remove(E e)把给定的对象在当前集合中删除
public boolean contains (Object obj)判断当前集合中是否包含给定的对象
public boolean isEmpty()判断当前集合是否为空
public int size()返回集合中元素的个数
public Object[] toArray()把集合中的元素,存储到数组中
public boolean addAll(Collection<? extends E> c)将集合中的元素添加到另一个集合中
public class CollectionApiDemo {
    public static void main(String[] args) {
        //1.HashSet 无序,不重复,无索引
        Collection<String> c = new ArrayList<>();

        //2.添加
        c.add("Java");
        c.add("java");
        c.add("false");
        c.add("true");

        //3.集合可以直接输出
        System.out.println(c);

        //4.清空元素
//        c.clear();
//        System.out.println(c);

        //5.从集合中删除
        c.remove("java");
        System.out.println(c);
        System.out.println(c.remove("ss"));
        System.out.println("-------------");

        //6.判断是否含有给定对象 contains
        System.out.println(c.contains("Java"));

        //7.isEmpty
        System.out.println(c.isEmpty());

        //8.size 大小
        System.out.println(c.size());

        //9.toArray() 转变为Object 类型 数组

        Object[] arr = c.toArray();
        System.out.println(Arrays.toString(arr));

        //10.addAll()   将集合添加到另一个集合中!!!
        Collection<String> c1 = new HashSet<>();
        c1.add("156");
        c1.add("123");

        c.addAll(c1);
        System.out.println(c);
    }
}
1.1Collection 迭代
  • 1迭代器Iterator
    • 遍历: 一个一个 把容器中的元素访问一遍;
    • 迭代器在Java中 的代表Iterator , 迭代器是集合的专门遍历方式
    • 第一步要先获取迭代器,Iterator iterator = 集合对象.iterator(); // 迭代器对象默认指向当前集合的0索引
    • 第二步: 通过以下方法遍历
      • boolean hasNext() ; 询问当前位置是否有元素存在,存在返回true , 否则false;
      • E next() ; 获取当前位置的元素,并同时将迭代器对象移向下一个位置,注意防止越界
    //使用迭代器 Iterator
    Collection<String> c1 = new ArrayList<>();
    c1.add("fa");
    c1.add("fifa");
    c1.add("monkey");
    //获取迭代器
    Iterator iterator = c1.iterator();

    while (iterator.hasNext()){
        System.out.println(iterator.next());
    }
  • 2加强for

    • 可以遍历集合与数组

    • 格式:

      • for (元素数据类型 变量名 : 数组/Collection集合){
        	//在此处使用 变量即可;
        }
        
    Collection<String> c1 = new ArrayList<>();
    c1.add("fa");
    c1.add("fifa");
    c1.add("monkey");
    //加强for
    for(String s : c1){
        System.out.println(s);
    }
  • 3forEach

    • Collection结合Lambda表达式,提供更便捷的遍历集合的方式

    • default void forEach(Consumer<? super T> action): 结合Lambda遍历集合

    Collection<String> collection = new ArrayList<>();
    collection.add("fa");
    collection.add("fifa");
    collection.add("hhh");
    collection.add("xhh");

    collection.forEach(new Consumer<String>() { //Consumer 一个函数式接口
        @Override
        public void accept(String s) {
            System.out.println(s);
        }
    });

    //Lambda表达式化简
     collection.forEach(s->{System.out.println(s);});

    //最终
    collection.forEach(System.out::println);            //优雅

image-20240116205144061

1.2List
  • List的实现类 ArrayList 和 LinkedList 有序,可重复,有索引
  • List的实现类的底层原理
    • ArrayList底层是基于 数组 实现的,查询元素快,增删速度慢;
    • LinkedList底层是基于 双链表实现的,查询速度慢,增删收尾元素块;

image-20240116205234688

public class ListDemo {
    public static void main(String[] args) {
        //1.创建List对象
        List<String> list = new ArrayList<>();

        //2.添加元素
        list.add("Java");
        list.add("HTML");
        list.add("java");
        list.add("CS");
        System.out.println(list);
        //指定索引,添加元素
        list.add(2,"JavaStrip");
        System.out.println(list);
        System.out.println("----------------------------");

        //3.删除元素 , 返回被删元素
        System.out.println(list.remove(2));
        System.out.println(list);
        System.out.println("---------------------------");
        //4.修改索引处元素,返回被修改的元素
        System.out.println(list.set(2, "JavaStrip"));
        System.out.println(list);

        //5.返回指定索引处元素
        System.out.println(list.get(3));
    }
}
1.2.1ArrayList

image-20240116210625332

  • 初始容量为10,满的时候,按照1.5倍扩容迁移。 size指向索引

  • 虽然存储的是地址,但是输出时为地址指向元素值

  • 注意: 使用 remove后, size会立即变小 , 需要再次检测当前位置

image-20240116211052756

1.2.2LinkedList

首尾操作:可以实现 栈和队列

public class LinkedListDemo2 {
    public static void main(String[] args) {
        //1.栈   后进先出
        LinkedList<String> list = new LinkedList<>();
//        list.addFirst("java");
//        list.addFirst("Java");
        list.push("java");               //push 优雅!!!
        list.push("Java");
        list.push("HTML");

        while (list.size()>0){
            System.out.println(list.pop()); //pop  优雅!!!
        }
        System.out.println("---------------------");
        //2.队列  先进先出
        LinkedList<String> list1 = new LinkedList<>();
        list1.addLast("java");
        list1.addLast("Java");
        list1.addLast("HTML");

        while (list1.size()>0){
            System.out.println(list1.removeFirst());
        }
    }
}
1.3Set
  • 无序:存储 与 取出顺序不一致, 每次取出顺序 很有可能不一致
  • 不重复:可以自动除去重复;
  • 无索引:没有带索引的方法,所以不能使用普通for 循环遍历, 也不能通过索引获取元素;

Set集合实现类特点:

  • HashSet : 无序、不重复、无索引;
    • LinkedHashSet:有序、不重复、无索引; 特殊:有序
  • TreeSet:排序、不重复、无索引; 特殊:排序(升序)

api 参考 Collection

1.3.1HashSet

底层原理:哈希表(散列表) 无序无索引

  • 哈希值

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

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

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

image-20240117110211900

image-20240117110221499

不重复

  • 右键generate ,点击 equals 和 hashCode 重写(如下) ;
  • 使用官方的方法 , 实体类所有内容完全一致也可以去重;
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return id == student.id && Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }
1.3.2LinkedHashSet

image-20240117112500474

1.3.3TreeSet

底层原理: 红黑树 排序(升序),不重复,无索引

image-20240117112655272

排序规则:

  • 基本类型:大小比较;字符串:从首位置开始匹配 通过ASCII

  • 接口Comparable< E > , 实现compareTo(类 o) {return 1/-1/0}; 依据成员变量大小,自动排序类对象

  • 函数式接口 Comparator< E >

    • Set<Apple> set4 = new TreeSet<>(new Comparator<Apple>() {
          @Override
          public int compare(Apple o1, Apple o2) {
              return 0;
          }
      });
      
public class TreeSetDemo {
    public static void main(String[] args) {
        //1.基本数据类型
        Set<Integer> set1 = new TreeSet<>();    //默认升序 , 比大小
        set1.add(123);
        set1.add(12);
        set1.add(1);
        System.out.println(set1);

        //2.字符串
        Set<String> set2 = new TreeSet<>();    //默认升序 , 比 首字符 ASCII
        set2.add("java");
        set2.add("Java");
        set2.add("你好");
        System.out.println(set2);

        //3.自定义 价格降序
        Set<Apple> set4 = new TreeSet<>(new Comparator<Apple>() {
            @Override
            public int compare(Apple o1, Apple o2) {
                return 0;
            }
        });
        // lambda表达式
        Set<Apple> set3 = new TreeSet<>((o1,  o2) -> Double.compare(o2.getPrice() , o1.getPrice()));
        set3.add(new Apple("红苹果","红色",12.5,500));
        set3.add(new Apple("青苹果","青色",10.5,900));
        set3.add(new Apple("绿苹果","绿色",15.5,700));
        set3.add(new Apple("蓝苹果","蓝色",8.5,500));

        //注意 ; 就近原则
        System.out.println(set3);
    }
}
//省略 setXxx() / getXxx()方法
public class Apple implements Comparable<Apple> {
    private String name;
    private String color;
    private double price;
    private int    weight;

    public Apple(){

    }

    public Apple(String name, String color, double price, int weight) {
        this.name = name;
        this.color = color;
        this.price = price;
        this.weight = weight;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Apple apple = (Apple) o;
        return Double.compare(apple.price, price) == 0 && weight == apple.weight && Objects.equals(name, apple.name) && Objects.equals(color, apple.color);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, color, price, weight);
    }

    @Override
    public String toString() {
        return "Apple{" +
                "name='" + name + '\'' +
                ", color='" + color + '\'' +
                ", price=" + price +
                ", weight=" + weight +
                '}';
    }

    /**
     * 按照重量 升序
     * @param o 对象
     * @return  1/-1/0
     */
    @Override
    public int compareTo(Apple o) {
        return this.getWeight() - o.getWeight() ;       //set 不可重复
//        return this.getWeight() - o.getWeight() >= 0 ? 1 : -1;
    }
}
二、Map

认识和使用

  • Map集合是一种 双列集合,每个元素包含两个数据;
  • Map集合的每个元素的格式:Key = value(键值对);
  • Map集合也称为 “键值对”集合

格式对比:

  • Collection [元素1,元素2,…]
  • Map {key1 = value , key2 = value2,key3 = value}

Map特点

  • Map的特点取决于 
  • Map的键是 无序的不重复的无索引的,值不做要求的(可重复)
  • Map集合后面重复的键对应的值 会覆盖前面的值
  • Map集合的键值对 都可以为null

Map集合实现类的特点

  • HashMap: 元素按照键 是 无序、不重复、无索引,值不做要求; 键(HashSet)
  • LinkedHashMap:元素按照键是 有序、不重复、无索引,值不做要求; 键(LinkedHashSet)
  • TreeMap:元素按照键是 排序、不重复、无索引的,值不做要求; 键(TreeSet)

Map常用Api

方法描述
Map<K,V> map = new HashMap<>();创建一个Map<K,V>对象
put(K,V)添加元素
clear()清空元素
boolean isEmpty()判空
public V get (Object key)获取指定键对应的值
V remove(Object key)删除整个元素
boolean containsKey(Object key)是否包含指定键
boolean containsValue(Object V)是否包含指定的值
public Set< K > keySet()获取全部键的集合
public Collection< V > values()获取全部值的集合
size()集合的大小
putAll()合并其他Map集合
public static void main(String[] args) {
    //1.创建一个Map<K,V>  对象
    Map<String,Integer> map = new HashMap<>();
    //添加元素 .put()
    map.put("鸿星尔克",3);
    map.put("红牛",3);
    map.put("枸杞",3);
    map.put("鸿星尔克",5);      //后 覆盖 前面
    map.put(null,null);
    System.out.println(map);

    //2.清空元素
    //        map.clear();
    //        System.out.println(map);

    //3.判空
    System.out.println(map.isEmpty());          //false

    //4.获取键对应的值:public V get (Object key)
    System.out.println(map.get("枸杞"));         //3
    System.out.println(map.get("枸杞1"));        //null

    System.out.println("-----------");
    //5.删除整个元素  V remove(Object key)
    System.out.println(map.remove("枸杞")); //3
    System.out.println(map.remove("枸杞1"));//null
    System.out.println(map);

    //6.包含指定键
    map.put("枸杞",3);
    System.out.println(map.containsKey("枸杞")); //true
    System.out.println(map.containsKey(null));  //true
    System.out.println(map.containsKey("拉菲")); //false

    //7.包含指定的值
    System.out.println(map.containsValue(5));    //true
    System.out.println(map.containsValue(3));    //true
    System.out.println(map.containsValue(null)); //true

    //8.获取全部键 的 集合  public Set<K> keySet()
    Set<String> set = map.keySet();
    System.out.println(set);

    //9.获取全部值 的 集合  public Collection<V> values()
    Collection<Integer> list = map.values();
    System.out.println(list);

    //10.集合的大小
    System.out.println(map.size());

    //11.合并其他Map集合(拓展) .putAll
    Map<String,Integer> map1 = new HashMap<>();
    map1.put("雀巢",12);
    map1.put("槟榔",13);
    map1.put("枸杞",100);         //覆盖!!!
    System.out.println(map);
    map.putAll(map1);
    System.out.println(map);
}
  • 遍历

    • 1键找值

      • 先获取Map集合的所有key的 Set集合 Set< K > keySet()
      • 遍历键的Set集合,然后通过键 提取对应值 V get(Object key)
    • 2键值对

      • 先把Map集合 转换为 存储键值对 实体类型的 Set集合 Set<Map.Entry<K,V>> entrySet()

      • 加强for 遍历Set ,然后提取键,提取值 K getKey() V getValue

        public class MapPrintDemo2 {
            public static void main(String[] args) {
                Map<String,Integer> m1 = new HashMap<>();
                m1.put("联想",1);
                m1.put("鸿星尔克",5);
                m1.put("耐克",0);
                m1.put("雀巢",3);
                System.out.println(m1);
        
                //无法确定 直接类型 来利用forEach
                //Set存储键值对对象  ,  map.entrySet()
                Set<Map.Entry<String, Integer>> entries = m1.entrySet();
                for (Map.Entry<String, Integer> entry : entries) {
                    //1.Entry接口泛型 存储 键值对 , 然后利用getKey , getValue
                    System.out.println(entry.getKey() +"===>"+ entry.getValue());
                }
            }
        }           
        
    • 3Lambda

      • default void forEach(BiConsumer<? super K , ? super V> action) 结合lambda遍历Map集合

      • map.forEach(new BiConsumer<String, Integer>() {
            @Override
            public void accept(String k, Integer v) {
                System.out.println(k + "===>" + v);
            }
        });
        
        map.forEach(( k,  v) -> System.out.println(k + "===>" + v));
        

image-20240117164925444

2.1HashMap

特点:

  • 常用
  • HashMap 是 Map里面的一个实现类;特点由键决定:无序、不重复、无索引
  • 没有额外需要学习的特有方法,直接使用Map里面的方法就可以了;
  • HashMap 跟 HashSet底层原理 是 一致的,都是哈希表结构;只是HashMap的每个元素包含两个值

实际,Set系列集合的底层就是Map实现的,只是Set集合中的元素只要键数据,不要值数据

  • 不重复 依赖 equals 与 hashCode , 自定义类 需要重写
2.2LinkedHashMap
  • 由键决定: 有序、不重复、无索引
  • 原理:底层数据结构 依然是哈希表,只是每个键值对元素 又额外多一个双链表的机制记录存储的顺序。
2.3TreeMap
  • 由键决定:可排序、不重复、无索引
  • 可排序:按照键数据的大小 ,默认升序; 只对键排序;也可以自定义规则与TreeSet一致
  • TreeMap跟 TreeSet的底层原理是一样的
三、工具类
3.1Collections
  • java.util.Collections是集合工具类;

  • Collections是操作集合的工具类,不属于集合;

  • 常用Api

方法名称描述
public static < T > boolean addAll(Collection < ? super T> c , element1, element2,…)给集合c对象批量添加元素
public static void shuffle(list<?> list)打乱list集合元素的顺序
    List<String> list = new ArrayList<>();
	//1.addAll(list , element1,element2,...)
    Collections.addAll(list,"faf","fifa","fei");
    System.out.println(list);

    //2.public static void shuffle(List<?> list)    //打乱list顺序 , 随机数 , 每次都不一样
    Collections.shuffle(list);
    System.out.println(list);
  • 排序
    • public static < T > void sort (list< T > list) 将集合元素按照默认规则排序(升序)
    • public static < T > void sort(list< T >list ,Comparator<? super T> c) 自定义规则排序
    List<Integer> integerList = new ArrayList<>();
    Collections.addAll(integerList,12,35,0,13);
    Collections.sort(integerList);      //升序
    System.out.println(integerList);
Collections.sort(list1, new Comparator<Apple>() {
    @Override
    public int compare(Apple o1, Apple o2) {
        return Double.compare(o2.getPrice(),o1.getPrice());//价格降序
    }
});
//lambda表达式
Collections.sort(list1, (o1,o2) -> Double.compare(o2.getPrice(),o1.getPrice()));
四、认识
4.1可变参数
  • 用在形参中,可以接收多个数据 , 可变参数只能放在形参列表的后面
  • 格式:数据类型 … 参数名
  • 本质:一个数组
public class ParamsDemo {
    public static void main(String[] args) {
        sum(12,23,43);
        sum(2);

        add(56,23,5,2,3);
    }

    /**
     * 形参里面只能有一个可变参数,可变参数只能放在形参列表的后面
     * @param arr 可变参数
     */
    public static void sum(int...arr){
        int number = 0;
        for (int i = 0; i < arr.length; i++) {
            number += arr[i];
        }
        System.out.println(number);
    }

    public static void add(int age , int...arr){
        System.out.println(age);
        System.out.println(Arrays.toString(arr));
    }
}
4.2不可变集合

image-20240117182520104

JDK 11

List<String> list = List.of("张三", "李四", "王五", "赵六");

Set<String> set = Set.of("张三","李四","王麻子","赵六");

Map<String, String> map = Map.of("张三", "南京", "李四", "北京", "王五", "上海", 
                                 "赵六", "广州");   // "张三" => "南京"
4.3泛型实例(补充)

1.自定义泛型方法

public class MethodDemo1 {
    public static void main(String[] args) {
        String[]  arr1 = {"java","Java","HTML"};
        printArray(arr1);
        Integer[] arr2 = {1,2,4,5,6};           //引用类型 <T>
        printArray(arr2);

        printArray(null);

        String[] arr = send(arr1);
        printArray(arr);
    }

    public static <T> T[] send(T[] arr){
        return arr;
    }
	//打印形如[1,2,3,4]
    public static <T> void printArray(T[] arr){// 限定  传输的数据类型
        if(arr != null){
            StringBuilder stringBuilder = new StringBuilder("[");
            for (int i = 0; i < arr.length; i++) {
                stringBuilder.append(arr[i]).append(i==arr.length-1?"":", ");
            }
            stringBuilder.append("]");
            System.out.println(stringBuilder);
        }else {
            System.out.println(arr);
        }
    }
}

2.通配符

public class LimitDemo {
    public static void main(String[] args) {
        ArrayList<BWM> arrayList1 = new ArrayList<>();
        arrayList1.add(new BWM());

        ArrayList<BEN> arrayList2 = new ArrayList<>();
        arrayList2.add(new BEN());

        go(arrayList1);
        go(arrayList2);

//        ArrayList<Dog> dogs = new ArrayList<>();
//        go(dogs);   应该为Car本身与子类
    }

    /**
     * 赛车比赛
     * @param arrayList 各类汽车集合
     */
    public static void go(ArrayList<? extends Car> arrayList){  //读入,做参数  (上界通配符),不能读入
        System.out.println(arrayList.size());
    }
}

class Dog{

}

class BEN extends Car{

}

class BWM extends Car{

}

class Car{

}
参考:

[Java不可变集合(超详解)_java不可变集合原理-CSDN博客](不可变集合)

  • 18
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值