对于java 集合的认知和使用

集合之间的关系

单列数据 Collection 可以重复 List 查改多 ArrayList 增删多 LinkedList 线程安全 Vector
不可重复 Set 存取顺序不同 HashSet 存取顺序相同 LinkedHashSet 需要排序 TreeSet

双列数据 Map 存取顺序不同 HashMap 存取顺序相同 LinkedHashMap 需要排序 TreeMap 读取文件 Properties 线程安全 Hasptable

Java集合

Java集合的Collection和Map的理解

有了数组,为何还要有集合呢?
这就要让集合和数组做一个比较了。
相同:两者都是容器,都是用来存储多个数据的
不同:

  1. 数组的长度是固定的,集合的长度是不固定的。
  2. 数组中存储的必须是同一类型的元素,可以存储任意类型的数据
    集合存储的可以不是同意类型的元素,但必须存储的是引用类型的数据, 但如果想存储基本类型的则就存储其包装类

在这里插入图片描述

提问:
1.为何集合的长度是不固定的呢?

2.基本类型的包装类的使用。

对各个集合的概括

集合的继承体系图形:
集合框架

Collection: 所有单列集合的父类(父接口),其下有List集合和Set集合
Map:所有双列集合的父类,其下有HashMap、TreeMap

Collection

子接口是List,其子类是Set

Collection的方法:
Collections.shuffe(List集合) 打乱集合顺序,只能是List集合
Collections.sort(List集合) 按默认规则给List集合排序(按ASCII码表排)
Collections.sort(List集合, comparator c)按照比较器顺序排序

Collections.sort(list, new Comparator<list集合里面放的类型>{
   
   
		@Override
		public int compare(Person o1, Person o2){
   
   
			//return o1.getAge() - o2.getAge();  按照年纪,升序o1-o2
			return o2.getAge() - o1.getAge();        //降序
		}
})

在这里插入图片描述

List

java.util.List接口继承于Collection接口,其实现类有ArrayList,LinkedList等
共有特点:有序,有索引,可重复

集合类型 数据结构 特点shuzu 用法 拓展
ArrayList 数组 增删慢,查询快,线程不安全 常用这个 底层是数组复制,且不定长 ;开发的时候也可作堆栈,队列
LinkedList 链表 增删快,查询慢 ,线程不安全 常用于首尾操作 底层是双向链表
Vector 数组 增删慢,查询快,线程安全 过时了
在这里插入图片描述

共有方法(来自collection):
集合对象.add()添加元素,也可以指定位置[add(index,element)],返回void
集合对象.get(int index) 获得元素,返回获得的元素
集合对象.remove(int index) 移除元素,返回被移除的元素
集合对象.set(index,element) 替换元素,用指定的元素替换索引位置的元素,返回被替换的元素

LinkedList集合的方法:
集合对象.addFirst(element) 把元素插入在集合最前面(index=0的位置)
集合对象.addLast(element) 把元素插入在集合最后面
集合对象.getFirst 或 getLast
集合对象.removeFirst 或removeLast
集合对象.pop() 从此列表所表示的堆栈处弹出一个元素
集合对象.push(Element) 将元素推入此列表的堆栈处
集合对象.isEmpty() 列表为空返回true

Set

继承自Collection,方法和Collection一致(如用add添加元素),只是更加严格。
实际上Set就是Collection,只 是行为不同。(这是继承与多态思想的典型应用:表现不同的行为。)Set不保存重复的元素

共有特点: 无序,不重复,无索引
特有特点: LinkedHashSet有序(因为底层有链表),不重复,无索引

Set接口的子类有:HashSet,LinkedHashSet,TreeSet

集合类型 数据结构 特点shuzu 用法 拓展
HashSet 哈希表 增删、查询快,线程不安全 常用这个 本身没有功能,底层依靠HashMap
LinkedHashSet 哈希表+链表 有序,增删、查询快 ,线程不安全 继承于HashSet
TreeSet 红黑树 能够对元素排序,默认升序 底层依赖于TreeMap

拓展
1.哈希表的数据结构:
jdk8前;哈希数组(默认长度16)+ 链表(单向)
jdk8后:哈希数组(默认长度16)+ 链表(单向)+ 红黑树
哈希表里面有一个加载因子0.75E,如果往哈希表中的存储元素达到75%就会自动扩容2倍。
当链表长度大于8,自动变成红黑树;当红黑树长度小于6自动变成链表

hashCode: 计算机算出来的十进制数,可以理解为对象的逻辑地址值,而不是物理地址值(内存分配给对象的地址值才是物理地址值)
字符串内容一样,哈希值一定一样;内容不一样,哈希值也可能一样。因为字符串重写了hashCode()方法

2.HashSet存储自定义类型如何保证元素唯一?
重写hashCode() 和 equals()方法

3.jdk8前 字符串地址是cahr【】数组;jdk8后是byte【】数组

4.集合的选择
元素可重复,则就用List集合----大量的增删操作,用LinkedList;反之ArrayList
元素不重复,则就用Set集合----存取顺序一致,用LinkedHashSet,反之HashSet;排序用TreeSet

Map

java.util.Map
双列集合的根接口,重写了toString
特点:键值对的数据存储结构,键唯一,值随意
其底下有;HashMap,LinkedHashMap,TreeMap

集合类型 数据结构 特点shuzu 用法 拓展
HashMap 哈希表 无序的 ,需要重写hashCode() 和 equals()保key唯一 常用这个
LinkedHashMap 哈希表+链表 有序的 ,需要重写hashCode() 和 equals()保key唯一
TreeMap 红黑树 能够对元素排序

在这里插入图片描述

Map常用方法
集合对象.put(k,v) 添加元素
集合对象.get(k) 通过key找value
集合对象.remove(k) 移除key对于的value,返回value
集合对象.set() 获取Map集合中所有的key,存储到set集合
集合对象.entrySet() 获取map集合重点所有键值对对象,存储在set集合
集合对象.containsKey(key) 判断集合是否有这个key

遍历Map集合的方法:
方法1.map集合对象.set() 获得所有的key的set集合,在遍历set集合找值
方法2.map集合对象.entrySet() 获得所有的键值对的set集合,遍历set集合,点getKey()和点getValue()获得键和值

我们的map集合想要保证key唯一,就得重写hashCode()和equals()方法

有了list为何还要有set?
因为List集合会保存重复的元素,而Set集合则不保存重复的元素

小结:
ArrayXxx:底层数据结构是数组,查询快,增删慢

LinkedXxx:底层数据结构是链表,查询慢,增删快

HashXxx:底层数据结构是哈希表。依赖两个方法:hashCode()和equals()

TreeXxx:底层数据结构是二叉树。两种方式排序:自然排序和比较器排序

集合(Collections,colletion(list,set),map)的区分

2021-05-30 09:53:04 星期日
接口和接口之间是继承,接口和类之间是实现。
List,Set,Map都重写了toStirng()方法,所以打印的是值,而不是地址值。

Collections

Collections 和Arrays(数组的工具类)一样是集合的工具类,用来对集合进行操作。
正因为是工具类,所以里面的方法是静态的,可以直接类名调用。
shuffle(List<?> list); 只能对list集合进行默认ASCII排序),list里面不能是实体类 sort(List<?> lis, Comparator); 自定义排序 ,list里面可以是实体类
addALL(集合名,元素1…元素2); 往集合最后面加0-N个元素

Comparator 比较器

是一个接口,利用实现类实现,重写int compare(T o1, T o2)方法。
return o1-o2(表示升序)
return o2-o1(表示降序)
例子:

package com.example.demo002.service;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.*;

public class test {
    public static void main(String[] args) {
        List<Person> list = new ArrayList<>();
        Collections.addAll(list,new Person("01", 10), new Person("02", 66), new Person("03", 22));
        System.out.println(list);
        Collections.sort(list, new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                // 前减后为升序,后减前为降序
                return o1.getAge() - o2.getAge(); // 此时是按照时间升序
            }
        });
        System.out.println(list);
    }
}

@Data
@NoArgsConstructor
@AllArgsConstructor
class Person {
    private String name;
    private int age;
}

查看原码我们可以知道Comparator接口被注解了@FunctionalInterface,所以时一个函数式接口,因此上面你都代码可以lombda简化成

// 方式一:
Collections.sort(list, (o1, o2) -> o1.getAge() - o2.getAge());
// 方式二:
Collections.sort(list, Comparator.comparingInt(Person::getAge));

Collection

Collection接口时单列集合的根接口,特点是有序,带索引,可重复。

###List集合
java.utils.List接口是继承了Collection接口;
ArrayList和LinkedList是List的实现类;
是有序,带索引,可重复

ArrayList 和 LinkedList 之间的区别

ArrayList
LinkedList

集合 数据结构 特点 性能 线程安全
ArrayList 数组 查询快,增删慢 效率高 线程不安全
LinkedList 双向链表 查询慢,增删快 效率低 线程安全

注意:
①ArrayList是数组结构,数组是定长的,默认为16长度,然后超过这个长度,就会System.copyof数组复制,从而ArrayList是不定长的。
②LinkedList,由于是双向链表结构所有,提供过了很多 首尾 的操作方法。
③在开发中,LinkedList也可以作为堆栈、队列的结构使用

Set集合

java.utils.Set接口是继承了Collection接口;
特点:无序,无索引,不重复(对于实体类,比较的也是值,值都相等那就是重复的,底层是hashmap,重写了equals和hashcode方法)
实现类有Hashset,LinkedHashSet,TreeSet (java.utils)
注意:
LinkedHashSet有序;

集合 数据结构 特点 性能 线程安全
实现类有Hashset HashMap(数组+链表+红黑树 = 哈希表) 查询增删快 效率高 线程不安全
LinkedHashSet 继承HashSet(哈希表+链表,从而有序了) 查询增删快 效率高 线程不安全
TreeSet 红黑树 可以进行Comparator排序 效率高 线程不安全

这儿涉及了好几种数据结构,打击可以看我这篇文章。

Map

java.utils.map是双列集合的根接口(单双列结合知道是存储的格式,双列是存放映射的K-V格式)
注意键k一定是唯一的,值v可以重复
特点: 键唯一值可重复,无序(LinkedHashMap是有序的),没有索引
实现类有HashMap,LinkedHashMap,TreeMap (java.utils)

集合 数据结构 特点
HashMap 数组(16/8扩容)+链表+红黑树 = 哈希表 无序
LinkedHashMap 是HashMap的子类,哈希表+链表 有序
TreeMap 红黑树 可以进行Comparator排序

注意:
重写 equals() 和 hashCode() ,比较的是里面属性的值,不重写比较的就是对象的地址值。

MAP的遍历

查看这篇[1]map遍历

对于集合对象 通过方法后 对象值的变化的认知

以list为例
假如我new了一个list对象,通过一个返回void的方法,此时有两种情况

第一种 调用集合的方法 - 里外对象一致

比如 list.add()
以list的方法往list里面您添加数据的时候,此时list的地址值没有发生变化,离开方法后,list对象里面还是有加进去的值。

第二种 通过new或者sql得到的集合数据 - 里外对象不一致

我们通过其他(非集合方法)方式获得的数据会重新生成一个对象,即时是直接把传入进来的对象接受这些数据,也是会指向另一个地址值。
看下图:
通过sql获得数据赋值给传入的集合对象,离开方法后,获取不到添加的值,因为地址值(hashcode()方法查看,例外两个集合对象是不同的结果)不一致

解决方法:
groupList.addAll(list);

  • groupList 传入的集合
  • list 添加了数据的集合

Map集合的遍历

Map集合的遍历有四种方法,但是整体来说就是两个方法向:

方向一:通过键找值;把键存在其他集合中,然后遍历集合

方法一: map.keySet()
方法四: map.values(); // 只能遍历所有的value,key无法操作

方向二:键值对;通过键值对获得对于的键和值

方法二:  map.entrySet().forEach() // 使用了lambda,所以里面的变量是final修饰的不能改变
方法三: map.entrySet().iterator() // 此时里面的变量是可以改变的
package com.e
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超人在良家-阿启

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值