JavaSE——Day10

1、Collection 接口

Collection是单例集合的顶层接口,它表示一组对象,这些对象被称为Collection元素,JDK不提供此接口的任何直接实现,它提供更加具体的子接口Set和List实现。创建Collection集合的对象采用多态的方式、具体实现类ArrayList。(Collection单例集合有:ArrayList、LinkedList、TreeSet、HashSet)(Map双例集合有:HashMap、Hashtable、ConcurrentHashMap)

常用方法:

boolean add(E e)
将指定的元素附加到此列表的末尾。

void clear()
从此列表中删除所有元素。

boolean contains(Object o)
返回true此列表是否包含指定的元素。

boolean remove(Object o)
从此列表中删除第一次出现的指定元素(如果存在)。

Object[] toArray()
以适当的顺序(从第一个元素到最后一个元素)返回一个包含此列表中所有元素的数组。

Iterator iterator()
返回此集合中元素的迭代器

boolean equals(Object o)
比较指定对象与此集合是否相等。

int hashCode()
返回此集合的哈希码值。

int size()
返回此集合中的元素数

1.1 List接口

list集合是有序集合,也被成为序列,用户可以精确控制每个元素在列表中的插入位置。用户可以通过它们的整数索引(在列表中的位置)访问元素,并在列表中搜索元素。与set集合不同,列表通常允许重复元素。

List集合特点:可重复,有序

常用子类:ArrayList、LinkedList 和 Vector(不推荐使用)

1.1.1、ArrayList 集合(优先考虑)

概念:List接口的可调整大小的数组实现。实现所有可选的列表操作,并允许所有元素,包括null. 除了实现List接口之外,该类还提供了操作内部用于存储列表的数组大小的方法。

特点:基于数组实现,查找效率高,但新增和删除效率低;线程不安全。

特有方法

void add(int index, E element)
在此列表中的指定位置插入指定元素。

E get(int index)
返回此列表中指定位置的元素。

int indexOf(Object o)
返回此列表中指定元素第一次出现的索引,如果此列表不包含该元素,则返回 -1。

int lastIndexOf(Object o)
返回此列表中指定元素最后一次出现的索引,如果此列表不包含该元素,则返回 -1。

E remove(int index)
移除此列表中指定位置的元素。

E set(int index, E element)
用指定的元素替换此列表中指定位置的元素。

	    ArrayList<String> list = new ArrayList<>();
        list.add("英伟达");
        list.add("英特尔");
        list.add("AMD");
        list.add(2,"死亡之眼");
        System.out.println(list.contains("AMD"));
        System.out.println(list.get(0));
        System.out.println(list.indexOf("AMD"));
        System.out.println(list.lastIndexOf("AMD"));
        System.out.println(list.remove(0));
        System.out.println(list.remove("AMD"));
        System.out.println(list.set(1,"Inter"));//返回被替代的元素
        Object[] str=list.toArray();
        System.out.println(Arrays.toString(str));

1.1.2 LinkedList

概念:LinkedList同时实现了List接口和Deque接口,也就是收它既可以看作一个顺序容器,又可以看作一个队列(Queue),同时又可以看作一个栈(stack)

特点:底层数据结构是链表,查询慢,增删快。线程不安全,效率高。

特有方法:

void addFirst(E e) 在此列表的开头插入指定的元素。

void addLast(E e)将指定的元素附加到此列表的末尾。

E getFirst() 返回此列表中的第一个元素。

E getLast() 返回此列表中的最后一个元素。

E removeFirst() 移除并返回此列表中的第一个元素。

E removeLast() 从此列表中删除并返回最后一个元素。

1.1.3 Vector

概念:Vector类实现可增长的对象阵列。像数组一样,它包含可以使用整数索引访问的组件

特点:线程安全,但是效率低

1.2 Set 接口

与List集合不同,Set接口的实现类创建的集合都是不包含重复元素的集合

Set集合特点:不包含重复元素的集合、没有带索引的方法所以不能使用普通遍历

常用子类:TreeSet(排序使用)、HashSet(效率高)、LinkedHashSet

1.2.1 TreeSet

概念:底层是二叉树算法实现。被用作排序

特点:元素不重复、排序根据传入参数进行排序(无参构造函数进行自然排序,带参构造函数根据参数排序接口排序)。没有索引,只能使用迭代器或增强for循环遍历

无参构造函数排序(需要Student类实现 Comparable接口,重写public int compareTo(Student s)方法;方法内容为排序规则)

 @Override
    public int compareTo(Student s) {
//        return 0;//只会添加一个进集合
//        return 1;//按存储顺序添加进集合
//        return -1;//按存储顺序逆序添加进集合
        int num=this.age-s.age;//按照年龄大小升序排列
//        int num=s.age-this.age;//按照年龄大小降序排列
        int num2= num==0?this.name.compareTo(s.name):num;
        return num2;
    }

带参构造函数排序(1、用匿名内部类)

		   TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                int num=s1.getAge()-s2.getAge();
                int num2= num==0?s1.getName().compareTo(s2.getName()):num;
                return num2;
            }
        });

(2、使用 static void sort(T[] a, Comparator<? super T> c)
根据由指定的比较器得出的顺序对指定的对象数组进行排序。)

1.2.2 HashSet

概念:底层数据结构是哈希表,对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的顺序一致、没有带索引的方法,所以不能使用普通for循环遍历、由于是Set集合,所以不包含重复元素的集合

原理:利用了哈希算法,在调用add方法时计算出对象的哈希值,用计算出的哈希值在集合中对比,没有相同则存入,如果有则用equals一个一个比较,比较结果为false则存入,true则不存。

使用HashSet时要重写类里面的hashCode和equals方法。

public static void main(String[] args) {
        HashSet<Student> hash = new HashSet<>();
		Student s1 = new Student("张三", 20);
        Student s2 = new Student("李四", 20);
        Student s3 = new Student("王五", 20);
        Student s4 = new Student("王五", 20);
        hash.add(s1);
        hash.add(s2);
        hash.add(s3);
        hash.add(s4);
        for (Student hashs:hash){
            System.out.println(hashs);
        }
 }

1.2.3 LinkedHashSet

特点:哈希表和链表实现Set接口具有可预测的迭代性、链表保证元素的有序、哈希表保证元素的唯一

初始容量为16,散列因子0.75。继承于HashSet,又基于LinkedHashMap存储所有元素,并用双向链表记录插入顺序

2、Map接口

​ Map接口下常用的子类有HashMap 、TreeMap 、Hashtable 和 ConcurrentHashMap 实现类,Map集合可以存储一对对象,即会一次性保存两个对象,存在key = value 结构,其最大的特点还是可以通过key 找到对应的value 值。

2.1 HashMap(常用)

请添加图片描述

实现原理:

  • HashMap根据计算出的哈希值对容量的取余获得集合操作下标。
  • 调用put方法时,需要检查数组大小,如果大于阈值则扩容
  • 计算哈希值,判断是否已有元素,无则直接插入,有则再判断是否存在key,存在则覆盖旧值,不存在则生成链表

常用方法:

V put(K key, V value)
将指定值与此映射中的指定键相关联。

boolean containsKey(Object key)
返回true此映射是否包含指定键的映射。

boolean containsValue(Object value)
返回true此映射是否将一个或多个键映射到指定值。

Set<Map.Entry<K,V>> entrySet()
返回Set此映射中包含的映射的视图。

Set keySet()
返回Set此映射中包含的键的视图。

Collection values()
返回Collection此映射中包含的值的视图。

        HashMap<Student, String> hm = new HashMap<>();
        Student s1 = new Student("刘备", 30,"蜀国");
        Student s2 = new Student("黄盖", 40,"东吴");
        Student s3 = new Student("周瑜", 27,"东吴");
        Student s4 = new Student("小乔", 24,"东吴");
        Student s5 = new Student("小乔", 25,"东吴");
        hm.put(s1,"蜀国");
        hm.put(s2,"东吴");
        hm.put(s3,"东吴");
        hm.put(s4,"东吴");
        hm.put(s5,"大汉");
        System.out.println(hm.containsKey(s1));
        System.out.println(hm.containsValue("大汉"));

        Set<Map.Entry<Student, String>> entries = hm.entrySet();
        for (Map.Entry<Student, String> entry:entries){
            String value = entry.getValue();
            System.out.println(entry.getKey().name+"来自"+value);
        }
        Set<Student> keys = hm.keySet();
        for (Student key:keys){
            System.out.print(key.getName()+" ");
        }
        System.out.println();
        Collection<String> values = hm.values();
        for (String value:values){
            System.out.print(value+" ");
        }

2.2 Hashtable

很多映射的常用功能与HashMap类似,不同的是它继承自Dictionary类,并且是线程安全的,任一时间只有一个线程能写Hashtable

2.3 TreeMap(推荐需要排序时使用)

TreeMap实现SortedMap<K,V>接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用Iterator遍历TreeMap时,得到的结果是排过序的。

使用TreeMap时,key必须实现Comparable接口或者在构造TreeMap传入自定义的Comparator,否则会在运行时抛出java.lang.ClassCastException类型的异常。

2.4 ConcurrentHashMap(推荐需要线程安全时使用)

线程安全原理:采用分段锁机制

很多映射的常用功能与HashMap类似

2.5 LinkedHashMap

LinkedHashMap是HashMap的一个子类,保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的,也可以在构造时带参数,按照访问次序排序。

2.6 HashMap、Hashtable、ConcurrentHashMap的区别

相同点:都是数据容器

不同点:

HashMap 线程不安全、效率高 、不保证存储顺序

Hashtable 线程安全、效率低 、不保证存储顺序

ConcurrentHashMap 线程安全、效率比较高(采用分段锁机制)不保证存储顺序

TreeMap 不保证存储顺序,但是会自动排序

LinkedHashMap 既保证存储顺序也保证查找方便

PS:将对象当成key存储时一定不要更改它,特别是自定义对象,容易发生数据结构错乱,会改变哈希值,导致查找的时候找不到。

3、哈希表概述

哈希表是一种数据结构,由对象数组+链表组成。根据哈希值对数组长度取余获取数组下标。对数据进行操作。默认哈希桶是16,散列因子0.75(当哈希桶存在数据75%时会进行扩容,扩容2倍,重构数据结构)。

PS: 在创建哈希表要思考好初始的桶数,过小容易多次重构数据结构,浪费性能,过大容易浪费空间。

散列因子过大虽然会减少空间的消耗,但是会增加查找成本,过小则会浪费大量空间。

哈希冲突

如果在计算哈希值得到数组下标后发现数组内存在数据,会生成一个链表,将数据存放到原数据后。

1.8版本新特性:

存放数据的数组空间被称为哈希桶

当哈希桶中的数据量大于8时,桶中的链表转换为红黑二叉树

当哈希桶中的数据量减少到6时,红黑二叉树转换为链表

4、迭代器和增强for循环

4.1 迭代器

4.1.1 Iterator

Iterator是一个接口,它是集合的迭代器。集合可以通过Iterator去遍历集合中的元素。

使用方法如下:

public static void main(String[] args) {
        Collection<String> ct = new ArrayList<String>();
        ct.add("hello");
        ct.add("java");
        ct.add("javase");
        ct.add("javaee");
        System.out.println(ct.contains("hello"));//判断集合中是否有这个元素
        //Iterator<E>	iterator()	返回此集合中元素的迭代器。
        Iterator<String> it = ct.iterator();//Iterator<E>	iterator()	返回此集合中元素的迭代器。
        while (it.hasNext()){//boolean	hasNext()	true如果迭代有更多元素,则返回
            String s = it.next();//E	next()	返回迭代中的下一个元素。
            System.out.println(s);
        }

    }

4.1.2 ListIterator

ListIterator列表的迭代器,允许程序员沿任一方向遍历列表,在迭代期间修改列表,并获取迭代器在列表中的当前位置。它继承于Iterator接口,只能用于各种List类型的访问。

常用方法

E next()
返回列表中的下一个元素并前进光标位置。

E previous()
返回列表中的前一个元素并向后移动光标位置。

int nextIndex()
返回后续调用将返回的元素的索引next()。

int previousIndex()
返回后续调用将返回的元素的索引previous()。

void remove()
从列表中删除由next()or返回的最后一个元素previous()(可选操作)。
void set​(E e)
用指定元素替换next()或 返回的最后一个元素previous()(可选操作)。

public static void main(String args[]){
// List.listIterator()列表的迭代器,允许程序员沿任一方向遍历列表,在迭代期间修改列表,并获取迭代器在列表中的当前位置
        ListIterator<String> lit = list.listIterator();
        //boolean	hasPrevious()
        //返回true此列表迭代器在反向遍历列表时是否有更多元素。
       while (lit.hasPrevious()){
           String s = lit.previous();
           System.out.println(s);
       }
        while (lit.hasNext()){
            String s=lit.next();
            if(s.equals("Java")){
                lit.add("java");//void	add(E e)将指定的元素插入列表(可选操作)。不会发生并发异常
            }
        }
        System.out.println(list);
}

4.2 增强for循环

目的:简化数组和Collection、Map集合的遍历
增强的格式
for(元素数据类型 变量名:数组或Collection集合){
元素就是变量名

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值