java---集合(数据结构)(重点)

2023-10-17 09:13:09 浏览数 (1)

13.1 概念

以前存储一组相同类型的数据使用数组,固定大小,具有连续性的存储空间。比如,5个长度的数组再存入数据时,如果现在已经存满,存入第六个元素,这时数组空间不够,扩容。Arrays.copyOf() , 很不方便,如果扩容频率太高,也影响你程序运行效率。集合来解决数组固定,如果扩容又影响效率的问题

UML图 类图

实线三角形是继承关系

虚线三角形是实现关系

箭头关联关系(结合两张图片,大概的了解一下)

iterator 迭代器对象,是所有集合类的父接口

重点

Vector 线程安全

List线路:

  • Collection 接口
  • List,Set,Queue接口
  • HashSet 类 ArrayList 类 LinkedList 类

Map线路:

  • HashMap 类 k-v 键值对
  • 下图是总结,各个数据结构底层

图一:

图二:

13.2 ArrayList集合(底层是数组)

ArrayList是数组的原理,一组连接性且具体相同类型的存储空间,没有长度的限制(扩容--扩容机制),它用解决不确定数量的元素的存储。

构造方法:

构造方法

案例

ArrayList()

创建一个初始长度为0的集合对象

ArrayList(Collection<? extends E> c)

ArrayList list=new ArrayList(newList) 用newList的元素去初始化list

ArrayList(int initialCapacity)

ArrayList list=new ArrayList(5) 调用一个初始的数组的存储容量

通过源码查看,构造方法案例ArrayList()并没有对数据数组分配长度,给的是一个为0个元的空数组

代码语言:javascript复制
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; //默认的0个元素的空数组 
transient Object[] elementData;  //集合存放数据的数组
public ArrayList() {
    //1、当new ArrayList的时候长度为0但到的是一个空数组
    //2、集合的底层数组储存结构是数组
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

ArrayList中的API (每个API都练一遍)

API

说明

boolean add(E e)

向集合中添加一个元素

list.add("hello");

void add(int index, E element)

向指定位置插入一个元素

list.add(1,"word")

Object get(int index)

根据指定的下标取出对应的元素,一般要配合循环使用

list.get(1)

boolean addAll(List list)

将一个集合添加到另一个集合中

list.addAll(newList)

clear()

清除集合中所有的元素

list.clear()

clone()

对集合元素进行克隆

ArrayList newList=(ArrayList)list.clone();

boolean contains(Object o)

判断指定元素在集合中是否存在,存在返回true,不存在返回false

list.contains("王政");

forEach(Consumer<? super E> action)

循环迭代集合中的元素

list.forEach(System.out::println)

indexOf(Object o)

判断指定元素在集合中是否存在,找到返回下标,找不到返回-1

list.indexOf("王政"); -1

isEmpty()

集合是空返回true,集合非空返回false

list.isEmpty();

iterator()

返回迭代器对象 iterator.hasNext() 判断指针的下一个元素是否存iterator.next()指针向下移动后并获出当前元素的值

Iterator iterator = students.iterator();

lastIndexOf(Object o)

从后向前判断指定元素在集合中是否存在,找到返回下标,找不到返回-1

remove(int index)

根据下标删除元素

list.remove(1);

remove(Object o)

根据元素对去删除集合中的元素,要保证删除指定的元素对象与集合中存放的元素对象是同一对象,内存地址一样。

list.remove("张鹏");list.remove(new Student(1,"张鹏")); new重新分配了地址,与元素不是同一对象,删除不了

set(int index, E element)

在指定下标位修改元素,直接修改覆盖

students.set(2,"陈朋");将下标2的元素修改为陈朋

size()

获取列表中元素的个数

list.size()

sort(Comparator<? super E> c)

对集合进行排序操作,参数是一个Comparator比较器

list.sort(new StudentComparator());

toArray()

将一个集合转换成一个数组

Object[] objects = students.toArray();转换的数组是什么类型取决于集合给的什么类型,像这样集合没有给具体的类型就是Object类型

集合的循环访问:

代码语言:javascript复制
//size()的案例
public class Main {
    public static void main(String[] args) {
        ArrayList students=new ArrayList();
        students.add("谢兴灵");
        students.add("张鹏");
        students.add("冯小龙");
        students.add("蔡金恩");
        students.add("王浩月");
        students.add(3,"沈查");
        //使用size来循环集合中的元素
        for (int i=0;i<students.size();i   ) {
            System.out.println(students.get(i));
        }

    }
}
代码语言:javascript复制
//第二种,foreach方式来访问
ArrayList students=new ArrayList();//这样创建出来的集合元素的类型就是Object
for (Object o:students) {
            System.out.println(o);
}
代码语言:javascript复制
//第三种,迭代器形式
// students.iterator() 获取一个Iterator对象
Iterator iterator = students.iterator();
//iterator.hasNext()  判断指针指向后一个元素是否存在数据,存在返回true,不存在返回false
while (iterator.hasNext()){
    //iterator.next() 真正将指针向后一个元素进行移动,并获取指向元素的值
     System.out.println(iterator.next());
}
代码语言:javascript复制
students.forEach(System.out::println);

addAll(List list)

代码语言:javascript复制
public class Main {
    public static void main(String[] args) {
        ArrayList students=new ArrayList();
        students.add("谢兴灵");
        students.add("张鹏");
        students.add("冯小龙");
        students.add("蔡金恩");
        students.add("王浩月");
        students.add(3,"沈查");

        ArrayList newList=  new ArrayList();
        newList.add("陶治");
        newList.add("浩楠哥");
        newList.add("王政");
        //成批量的将一个集合内容添加到另一个集合中
        students.addAll(newList);

        students.forEach(System.out::println);

    }
}

clear清除集合中所有的元素

代码语言:javascript复制
public class Main {
    public static void main(String[] args) {
        ArrayList students=new ArrayList();
        students.add("谢兴灵");
        students.add("张鹏");
        students.add("冯小龙");
        students.add("蔡金恩");
        students.add("王浩月");
        students.add(3,"沈查");

        ArrayList newList=  new ArrayList();
        newList.add("陶治");
        newList.add("浩楠哥");
        newList.add("王政");
        //成批量的将一个集合内容添加到另一个集合中
        students.addAll(newList);

        System.out.println(students.size());
        System.out.println("=====================清除后======================");
        students.clear();//清除
        System.out.println(students.size());
    }
}

clone()

代码语言:javascript复制
public class Main {
    public static void main(String[] args) {
        ArrayList students=new ArrayList();
        students.add("谢兴灵");
        students.add("张鹏");
        students.add("冯小龙");
        students.add("蔡金恩");
        students.add("王浩月");
        students.add(3,"沈查");

        ArrayList newStudents=(ArrayList) students.clone();


        newStudents.forEach(System.out::println);
    }
}

contains查找某元素在集合中是否存在

代码语言:javascript复制
import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        ArrayList students=new ArrayList();
        students.add("谢兴灵");
        students.add("张鹏");
        students.add("冯小龙");
        students.add("蔡金恩");
        students.add("王浩月");
        students.add(3,"沈查");
        System.out.println(students.contains("王政"));  //false
        System.out.println(students.contains("沈查"));   //true
    }
}

forEach(Consumer<T> action); //Consumer接口

代码语言:javascript复制
public class Main {
    public static void main(String[] args) {
        ArrayList students=new ArrayList();
        students.add("谢兴灵");
        students.add("张鹏");
        students.add("冯小龙");
        students.add("蔡金恩");
        students.add("王浩月");
        students.add(3,"沈查");
        students.add("张跃成");

        /*for (Object o:students) {
            String str=o.toString();
            if(str.startsWith("张")){
                System.out.println(str);
            }
        }*/
        /**
        当前这个结构与上面的for是一样的道理这里的o就是迭代变量, ->因定写法,{ }中就是上面for的{}
        */
        students.forEach(o -> {
            String str=o.toString();
            if(str.startsWith("张")){
                System.out.println(str);
            }
        });
    }
}

indexOf(值)查找元素在集合中是否存在,找到返回下标,找不到返回-1

代码语言:javascript复制
public class Main {
    public static void main(String[] args) {
        ArrayList students=new ArrayList();
        students.add("谢兴灵");
        students.add("张鹏");
        students.add("冯小龙");
        students.add("蔡金恩");
        students.add("王浩月");
        students.add(3,"沈查");
        students.add("张跃成");

        System.out.println(students.indexOf("张鹏"));
        System.out.println(students.indexOf("王政"));
    }
}

isEmpty() 集合空返回true,非空返回false

代码语言:javascript复制
public class Main {
    public static void main(String[] args) {
        ArrayList students=new ArrayList();
        System.out.println(students.isEmpty());//true
        students.add("谢兴灵");
        students.add("张鹏");
        students.add("冯小龙");
        students.add("蔡金恩");
        students.add("王浩月");
        students.add(3,"沈查");
        students.add("张跃成");
        System.out.println(students.isEmpty());//false
    }
}

remove(index) 根据下标删除 remove(Object) 根据对象删除

代码语言:javascript复制
public class Main {
    public static void main(String[] args) {
        ArrayList students=new ArrayList();
        students.add("谢兴灵");
        students.add("张鹏");
        students.add("冯小龙");
        students.add("蔡金恩");
        students.add("王浩月");
        students.add(3,"沈查");
        students.add("张跃成");

        System.out.println("第一次删除");
        students.remove(1);//删除元素下标为1的值
        students.forEach(System.out::println);

        System.out.println("第二次删除");
        students.remove("蔡金恩"); //根据元素在再删除数据 这里容易迷惑
        students.forEach(System.out::println);
    }
}
代码语言:javascript复制
public class Main1 {
    public static void main(String[] args) {
        ArrayList list=new ArrayList();
        list.add(new Student(1,"谢兴灵"));
        list.add(new Student(2,"张鹏"));
        list.add(new Student(3,"冯小龙"));
        list.add(new Student(4,"蔡金恩"));
        list.add(new Student(5,"浩楠哥"));
        
        //list.remove(new Student(4,"蔡金恩"));//这样删除不了,因为重新new了就不再是同一对象
        list.remove(list.get(3));//这样才能删除 先去集合中取出对象,再删除。

        System.out.println(list);
    }

    static class Student{
        private Integer id;
        private String name;

        public Student(Integer id, String name) {
            this.id = id;
            this.name = name;
        }

        @Override
        public String toString() {
            return "Student{"  
                    "id="   id  
                    ", name='"   name   '''  
                    '}';
        }
    }
}

set(int index,Object e);修改指定下标的元素

代码语言:javascript复制
public class Main {
    public static void main(String[] args) {
        ArrayList students=new ArrayList();
        students.add("谢兴灵");
        students.add("张鹏");
        students.add("冯小龙");
        students.add("蔡金恩");
        students.add("王浩月");
        students.add(3,"沈查");
        students.add("张跃成");

        students.set(2,"陈朋");
        students.forEach(System.out::println);
    }
}

sort(Comparator<? super E> c) 对集合元素进行排序

代码语言:javascript复制
public class Main1 {
    public static void main(String[] args) {
        ArrayList list=new ArrayList();
        list.add(new Student(18,"谢兴灵"));
        list.add(new Student(12,"张鹏"));
        list.add(new Student(33,"冯小龙"));
        list.add(new Student(24,"蔡金恩"));
        list.add(new Student(15,"浩楠哥"));
        list.sort(new StudentComparator()); //开始排序
        list.forEach(System.out::println);
    }
}
//实现Comparator比较器
public class StudentComparator implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.getId()-o2.getId();
    }
}

toArray() 将集合转换成数组

代码语言:javascript复制
public class Main {
    public static void main(String[] args) {
        ArrayList students=new ArrayList();
        students.add("谢兴灵");
        students.add("张鹏");
        students.add("冯小龙");
        students.add("蔡金恩");
        students.add("王浩月");
        students.add("张跃成");
        Object[] objects = students.toArray();
    }
}

13.3 LinkedList 集合

语法: LinkedList list=new LinkedList ();

LinkedList 非线程安全,链表做为底层实现。ArrayList也是非线程安全,使用的是数组做为底层实现。

代码语言:javascript复制
public class Main2 {
    public static void main(String[] args) {
        List<Integer> list=new LinkedList<>();
        //同时开启30个线程,每个线程向集合填入一个数,这时就会出资源争抢,从而引发异常
        for (int i = 1; i <= 30 ; i  ) {
            final int j=i;
            new Thread(()->{
                list.add(j);
                System.out.println(list);
            }).start();
        }
    }
}

数组:

1、我们以后的使用习惯会经常使用ArrayList。用它来进行数据运输工作。

2、ArrayList是一组连接性的存储空间,好处查找方便。查找效率比较高,但是插入效率比较低。

链表:

1、不是连续性存储单元,每个对象之间有一个关联关系,插入的只需要修改相邻两个对象之间的关联关系就好了,所以插入的效率比较高

2、链表是以碎片形式在内存中存在,它的查找效率就比较低

13.4 HashSet

hashSet 无序列表(不允许排序)。ArrayList底层由数组实现,数组是一组有序的存储空间,LinkedList由链表实现,链表也有顺序关联。HashSet没有顺序可言,就没有下标的概念,并且HashSet中不允许出现重复的数据。

构造方法

方法

说明

案例

HashSet()

构造一个新的空集合

Set set=new HashSet()

HashSet(Collection<? extends E> c)

用一个集合来构造一个新的Set

Set set = new HashSet(list)

常用API

方法名

说明

add(E e)

向Set集合中添加一个元素

set.add("张鹏")

size()

返回set集合中元素的个数

set.size();

clear()

清空set集合中所有元素

set.clear()

isEmpty()

判断set集合是否有元素存在,没有返回true,有返回false

set.isEmpty()

remove(E e)

删除set集合中的元素,只能根据对象去删除元素

set.remove(e)

contains(E e)

判断set集合某个元素是否存在

set.contains(e)

注意set集合不能使用for(int i=0;i<set.size();i ){}结构来对set进行循环拿值,只能使用迭代器的形式。

代码语言:javascript复制
public class Main6 {
    public static void main(String[] args) {
        Set<String> set=new HashSet<>();
        set.add("张鹏");
        set.add("谢兴灵");
        set.add("冯小龙");
        set.add("蔡金恩");

        System.out.println(set.isEmpty());
        set.remove("张鹏");
        System.out.println(set.contains("张鹏"));
        set.clear();
        for (String s: set) {
            System.out.println(s);
        }
    }
}

有一堆同学的姓名,这一堆同学的姓名中可能会有重复的,要求将重复的姓名删除,只保留一个(去重)。

代码语言:javascript复制
public class Main6 {
    public static void main(String[] args) {
        Set<String> set=new HashSet<>();
        set.add("张鹏");
        set.add("谢兴灵");
        set.add("冯小龙");
        set.add("蔡金恩");
        set.add("张鹏");//重复姓名
        set.add("谢兴灵");

        for (String s: set) {
            System.out.println(s);
        }
    }
}
结果:
张鹏
冯小龙
谢兴灵
蔡金恩

结论:添加重复的内容不会报错,但是添加不成功。

解决方案:

代码语言:javascript复制
public class Main6 {
    public static void main(String[] args) {
        List<String> list=new ArrayList<>();
        list.add("张鹏");
        list.add("谢兴灵");
        list.add("冯小龙");
        list.add("蔡金恩");
        list.add("张鹏");
        list.add("谢兴灵");
        Set<String> set=new HashSet<>(list);
        for (String s: set) {
            System.out.println(s);
        }
    }
}

HashSet底层用什么实现,HashMap,如何实现。map--> key - value 键值对map.put(key, value),HashSet添加时会将值存入到map的键中,而map的中的值使用的是一个Object类型的常量。所有的add添加都使用这个固定常量。

代码语言:javascript复制
public boolean add(E e) {
        return map.put(e, PRESENT)==null;
}

13.5 TreeSet

可排序的列表,TreeSet会对内部的值进行自然排序

代码语言:javascript复制
public class Main6 {
    public static void main(String[] args) {

        Set<Integer> set=new TreeSet<>();
        set.add(53);
        set.add(19);
        set.add(77);
        set.add(8);
        set.add(100);
        set.add(100);//重复数据
        for (Integer s: set) {
            System.out.println(s);
        }
    }
}
结果:
8
19
53
77
100
代码语言:javascript复制
public class Main6 {
    public static void main(String[] args) {

        Set<Student> set=new TreeSet<>();
        set.add(new Student(18, "张鹏"));
        set.add(new Student(99, "谢兴灵"));
        set.add(new Student(37, "冯小龙"));
        set.add(new Student(56, "蔡金恩"));

        set.forEach(System.out::println);
    }
}
运行结果
 Exception in thread "main" java.lang.ClassCastException: com.qf.entitys.Student cannot be cast to java.lang.Comparable
    at java.util.TreeMap.compare(TreeMap.java:1290)
    at java.util.TreeMap.put(TreeMap.java:538)
    at java.util.TreeSet.add(TreeSet.java:255)
    at Main6.main(Main6.java:9)

结论,因为TreeSet会自然排序,普通的类直接丢进TreeSet中会报错, 解决方案,Student中实现Comparable接口。

代码语言:javascript复制
package com.qf.entitys;

public class Student implements Comparable<Student> {
    public Student(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    private Integer id;
    private String name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Student{"  
                "id="   id  
                ", name='"   name   '''  
                '}';
    }


    @Override
    public int compareTo(Student o) {
        return this.getId()-o.getId();
    }
}

重写之后,上面的调用代码可正常运行了。

13.6 HashMap 重点

HashMap是以Key(键)--Value(值) 通过Key去寻找对应的值,江湖简称K-V键值对。例如,家庭地址(键),520平米的大平层就是(值),通过标识(家庭地址)可以寻找到你的家的那片空间。

语法:

Map<键的类型,值的类型> maps=new HashMap<>();

代码语言:javascript复制
Map<String,Integer> maps=new HashMap<>();

HashMap 底实现 数组 链表(哈希表) 红黑树(二叉树的一种)

构造方法:

方法名

说明

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 。

负载系数说的是如果这个默认长度为16的数组元素存储率到达75%的时候,需要重新创建数组扩容再来存放数据。一般使用HashMap()默认的就够了。

API:

方法名

说明

案例

put(K key, V value)

将指定的值与此映射中的指定键相关联

maps.put("zhangsan","张三");

get(Object key)

返回到指定键所映射的值

maps.get("zhangsan");

entrySet()

返回此Map中包含的映射的Set的集合,返回的是Map.Entry这样的一个类型的Set,Set<Map.Entry<K,V>>

Set<Map.Entry<K,V>> set=maps.entrySet();

keySet()

返回此Map中包含的映射的Set的集合,返回的是Set<K>

Set<String> key=maps.keySet()

values()

返回此Map中所有值的集合

Collection<V> list=maps.values()

isEmpty()

Map中没有元素返回true,否则返回false

maps.isEmpty()

containsKey(Object key)

判断map中指定的键是否存在,存在返回true,不存在返回false

maps.containsKey("zhangsan")true

containsValue(Object value)

判断map中指定的值是否存在,存在返回true,不存在返回false

maps.containsValue("张三")true

putAll(Map<? extends K,? extends V> m)

将另一个map添加到本map中

maps.putAll(oldMap);

remove(Object key)

根据key 删除元素

maps.remove("zhangpeng")

remove(Object key,Object value)

根据key和value删除元素,key和value要与元素中的一致才能删除

names.remove("zhangpeng","谢兴灵");删除不掉names.remove("zhangpeng","张鹏");删除了

size()

返回map的元素个数

maps.size()

clear()

清空这个map

maps.clear()

  • Map.Entry<K,V> 这个接口是就键-值对的对象 这个接口中提供了

方法名

说明

K getKey();

获取当前键值对中的键

V getValue();

获取当前键值对中的值

代码语言:javascript复制
public class Main10 {
    public static void main(String[] args) {
        Map<String,String> names=new HashMap<>();
        names.put("zhangsan","张三");
        names.put("lisi","李四");
        names.put("wangwu","王武");
        names.put("zhuliu","朱牛");
        names.put("zhaoqi","赵妻");
        //names Map中存入的是多个键值对,所以拿出来的Entry对象也应该是多个,Set<Map.Entry<String, String>>
        Set<Map.Entry<String, String>> entries = names.entrySet();
        for (Map.Entry e: entries) {
            System.out.println(e.getKey() "--------------" e.getValue());
        }
    }
}

keySet() 返回键的集合 Set<K>

代码语言:javascript复制
//keySet() 返回键的集合    Set<K>
Set<String> keys = names.keySet();
for (String k: keys) {
    //拿到了键就可以通过 get方法拿值
    System.out.println(k "--------------" names.get(k));
}

values() 获取所有值的集合

代码语言:javascript复制
Collection<String> values = names.values();
for (String v: values) {
       System.out.println(v);
}

完整案例:

代码语言:javascript复制
import java.util.*;

public class Main10 {
    public static void main(String[] args) {
        Map<String,String> names=new HashMap<>();
        names.put("zhangsan","张三");
        names.put("lisi","李四");
        names.put("wangwu","王武");
        names.put("zhuliu","朱牛");
        names.put("zhaoqi","赵妻");
        //第一种迭代
        Set<Map.Entry<String, String>> entries = names.entrySet();
        for (Map.Entry e: entries) {
            System.out.println(e.getKey() "--------------" e.getValue());
        }
        //第二种迭代
        Set<String> keys = names.keySet();
        for (String k: keys) {
            System.out.println(k "--------------" names.get(k));
        }
        //第三种迭代
        Collection<String> values = names.values();
        for (String v: values) {
            System.out.println(v);
        }
    }
}

putAll(oldMap)

代码语言:javascript复制
Map<String,String> oldMap=new HashMap<>();
//HashSet存储时值是存在HashMap的键中  HashSet不允许有重复值
        oldMap.put("zhangpeng","张鹏");
        //oldMap.put("zhangpeng","谢兴灵");//如果键重复值就是后面的覆盖前面的
        oldMap.put("xiexingling","谢兴灵");
        Map<String,String> names=new HashMap<>();
        names.put("zhangsan","张三");
        names.put("lisi","李四");
        names.put("wangwu","王武");
        names.put("zhuliu","朱牛");
        names.put("zhaoqi","赵妻");
        names.putAll(oldMap);
        names.keySet().forEach(System.out::println);
        System.out.println("=======================");
        names.values().forEach(System.out::println);

在项目中时,多数情况下,Map中的值是一个类的对象,Map中的键是这个类唯一能代表这个人的属性

代码语言:javascript复制
public class Main10 {
    public static void main(String[] args) {
        //唯一的属性会作为键存在
        Map<Integer, Student> stuMap=new HashMap<>();
        Student stu1=new Student(1,"张鹏");
        Student stu2=new Student(2,"谢兴灵");
        Student stu3=new Student(3,"冯小龙");
        Student stu4=new Student(4,"蔡金恩");
        Student stu5=new Student(5,"陈朋");
        stuMap.put(stu1.getId(),stu1);
        stuMap.put(stu2.getId(),stu2);
        stuMap.put(stu3.getId(),stu3);
        stuMap.put(stu4.getId(),stu4);
        stuMap.put(stu5.getId(),stu5);

        System.out.println(stuMap.get(3).getName());
    }
}

13.7 HashTable 和 TreeMap

这两个的操作API与HashMap一样

1、HashTable: jdk1.1版本就出现的一个东西,它内部实现使用的是数组 链表

2、TreeMap , HashMap没办法排序,如果想要对元素进行自然排序的时候就使用TreeMap;

13.8 Collections工具类

Collections内部提供了很多的方法对集合进行操作:

addAll(list, T...element),将多个元素添加到集合中.

代码语言:javascript复制
List<String> list=new ArrayList<>();
  Collections.addAll(list,"张鹏","谢兴灵","冯小龙");
  System.out.println(list);

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

代码语言:javascript复制
List<String> list=new ArrayList<>();
        Collections.addAll(list,"张鹏","谢兴灵","冯小龙");
          System.out.println(Collections.binarySearch(list, "谢兴灵"));
        System.out.println(list);

emptyList() emptySet() emptyMap() 返回一个空的不可变的集合

代码语言:javascript复制
List<Object> objects = Collections.emptyList();
  objects.add("张三");
  System.out.println(objects.get(0));

返回的是一个不可变的List所以无法对返回的结果的元素进行改变,用处再于某一个方法的返回值如果有可能为null的时候用这个东西来替换。

fill(List<? super T> list, T obj)

代码语言:javascript复制
List<String> list=new ArrayList();
        list.add("张鹏");
          list.add("谢兴灵");
          Collections.fill(list,"冯小龙");
          System.out.println(list);
  //会将集合中所有的元素都替换为冯小龙

max(Collection<? extends T> coll)

min(Collection<? extends T> coll)

代码语言:javascript复制
List<String> list=new ArrayList();
          list.add("张鹏");
          list.add("谢兴灵");
        System.out.println(Collections.max(list));
          System.out.println(Collections.min(list));

如果两个自定义对象要比较的话必须要实现Comparable

reverse(List<?> list) 反向排序元素的位置

代码语言:javascript复制
List<String> list=new ArrayList();
          list.add("张鹏");
          list.add("谢兴灵");
          list.add("冯小龙");
          System.out.println(list);
          System.out.println("===================================");
          Collections.reverse(list);
          System.out.println(list);

shuffle(List<?> list) 随机排列元素的位置

代码语言:javascript复制
List<String> list=new ArrayList();
          list.add("张鹏");
          list.add("谢兴灵");
          list.add("冯小龙");
          System.out.println(list);
          System.out.println("===================================");
          Collections.shuffle(list);
          System.out.println(list);

sort(List<T> list) 对元素进行排序

代码语言:javascript复制
List<Integer> list=new ArrayList();
          list.add(53);
          list.add(45);
          list.add(49);
          System.out.println(list);
          System.out.println("===================================");
          Collections.sort(list);
          System.out.println(list);

swap(List<?> list, int i, int j) 交换指定位置上的元素

代码语言:javascript复制
List<Integer> list=new ArrayList();
  list.add(53);
  list.add(45);
  list.add(49);
  Collections.swap(list,0,2);
  System.out.println(list);

synchronizedList(List<T> list)

synchronizedSet(Set<T> set)

synchronizedMap(Map<K,V> m)

用当前的集合构造一个线程安全的集合对象

代码语言:javascript复制
public static void main(String[] args) {
  
          List<Integer> list=Collections.synchronizedList(new ArrayList<>());
  
          for (int i = 1; i <= 30 ; i  ) {
              final int j=i;
              new Thread(()->{
                  list.add(j);
                  System.out.println(list);
              }).start();
          }
      }

13.9 泛型

泛型,一般在类上进行定义可以用于全类的范围,如果在方法上定义只能在方法中使用

泛型就是使用一个任意命名的替代符去代替即将使用的类型,这是一种抽象概念。

约定俗成:

E entity-->实体的意思

K key--> 键

V value-> 值

T target-> 目标对象

public class 类名<E>{

}

这里的E是一个类型,具体。是什么类型要在创建这个对象的时候才去指定。 var i="123"; var i=1; var i=3.14;

代码语言:javascript复制
public class MyList<E> implements List<E> { //这里是对泛型的定义 E 可以随机写 一般大写单个字母 
    @Override
    public boolean add(E e) {  //  E 上面定义的泛型,现在不知道什么类型,等对象创建的时候给定具体的类型
        return false;
    }
}
public class Main2 {
    public static void main(String[] args) {
        List<Student> list=new MyList<>(); //创建MyList对象,给定了一个Student,E就是Student.
        list.add(new Student(1,"张鹏"));//调用add方法只能传Student数据进去
    }
}

泛型写在方法上时

public <T> void 方法名(T t){

}

代码语言:javascript复制
public class MyList<E> {

    public void add(E e){
        System.out.println(e);
    }

    //参数给什么值 T就代表什么类型
    public <T> void show(T t){
        System.out.println(t);
    }
}

public class Main2 {
    public static void main(String[] args) {
        MyList<Integer> list=new MyList<>();
        list.add(12);
        list.show(1);//T int
        list.show(3.14);// T double 
        list.show("helloworld");//T String

    }
}

无界,上界,下界

代码语言:javascript复制
private static class MyList{
        public <T> void show(T t){
            System.out.println(t);
        }

        //无界  List<?> list  所有类型的集合都接收
        //List<?>=List<Object>
        public void show1(List<?> list){
            System.out.println(list);
        }
        //上界 List<? extends 父类> list  父类及所有子类的集合接收
        public void show2(List<? extends Number> list){
            System.out.println(list);
        }
        //下界 List<? super 类名> list  只接收指定类名的集合
        public void show3(List<? super Number> list){
            System.out.println(list);
        }
    }

0 人点赞