JavaSE-集合框架

集合框架


JCF: Java Collection Framework

由于操作数组很麻烦: 扩容,缩容

Java搞了一个集合框架来代替数组: 在数组的基础之上封装了一层,更方便开发者使用。

集合框架的基本结构

在这里插入图片描述

简化版:

在这里插入图片描述

Collection: 父接口->管理列

​		List: 子接口

​				**ArrayList: 实现类 , 存放有序的,不唯一的数据**

​				LinkedList: 实现类

​		Set: 子接口

​				**HashSet: 实现类, 存放无序,唯一的数据, 通常用来去重**

​				TreeSet:实现类

Map: 父接口 -> 管理键值对  key => value

​		**HashMap: 实现类: 存放键值对**

​		TreeMap: 实现类

ArraysList***

在这里插入图片描述

初始化

在这里插入图片描述

 // 初始化集合
ArrayList list1 = new ArrayList();
ArrayList list2 = new ArrayList(10);
ArrayList list3 = new ArrayList(list2);
// 多态的方式
List list4 = new ArrayList();

增删改查

增加

在这里插入图片描述

// 添加元素- 直接添加到末尾
list4.add(1);
list4.add("2");
list4.add(true);

// 输出
System.out.println(list4);
list4.add(1, "jack");
System.out.println(list4);

// 添加一个集合
list1.add("rose");
list1.add("lucy");
list4.addAll(list1);
System.out.println(list4);

// 指定位置插入集合
list2.add("gxa");
list4.addAll(3, list2);
System.out.println(list4);
删除

在这里插入图片描述

// 删除数据-remove
System.out.println(list4.remove(0));
System.out.println(list4);
list4.remove("lucy");
System.out.println(list4);

修改

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ff0VC8t7-1628725931398)(C:\Users\一路向北\AppData\Roaming\Typora\typora-user-images\image-20210809141245491.png)]

// 修改数据-set
System.out.println(list4.set(0, "JACK"));
System.out.println(list4);

获取数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mqBcj6e8-1628725931399)(C:\Users\一路向北\AppData\Roaming\Typora\typora-user-images\image-20210809141612152.png)]

// 查询
// 获取对应的元素
System.out.println(list4.get(2));
// 获取对应元素的下标
System.out.println(list4);
list4.add(2, "tom");
list4.add("tom");
System.out.println(list4);
// 没有元素 -1
System.out.println(list4.indexOf("1"));
System.out.println(list4.indexOf("tom"));
System.out.println(list4.lastIndexOf("tom"));
// 是否包含
System.out.println(list4.contains("1"));
System.out.println(list4.contains("tom"));

遍历

iterator()

在这里插入图片描述

// 获取迭代器
Iterator iterator = list4.iterator();
// 判断是否有下一个元素
while (iterator.hasNext()){
    // 取出对应的元素
    System.out.println(iterator.next());
}
for

需要知道范围

size()方法获取集合的长度。

注意: 这个size不是底层数组的长度

for (int i = 0; i < list4.size(); i++) {
    System.out.println(list4.get(i));
}
foreach

使用最多的方式

// foreach的方式-使用最多
for (Object o : list4) {
    System.out.println(o);
}

泛型的使用

菱形语法

规定集合的数据类型

泛型只能使用: 引用数据类型, 不能使用基本数据类型

泛型的出现: 减少出错的概率。

List<Integer> nums = new ArrayList<>();
nums.add(1);
nums.add(1);
nums.add(1);
nums.add(1);

for (Integer num : nums) {
    System.out.println(num);
}
// 用户列表
List<Member> members = new ArrayList<>();
members.add(new Member("jack1", "123123", 18));
members.add(new Member("jack2", "123123", 19));
members.add(new Member("jack3", "123123", 20));
members.add(new Member("jack4", "123123", 21));

for (Member member : members) {
    System.out.println(member);
}

底层

ArrayList的底层是通过数组来存放数据的:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2tRaiC4s-1628725931403)(C:\Users\一路向北\AppData\Roaming\Typora\typora-user-images\image-20210809151435676.png)]

从构造器的底层来看: 是为了初始化底层的elementData

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l4pA9cx1-1628725931404)(C:\Users\一路向北\AppData\Roaming\Typora\typora-user-images\image-20210809152149968.png)]

从添加的方法: 当底层的数组长度不够的时候才会去扩容。

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U5ahwXUf-1628725931407)(C:\Users\一路向北\AppData\Roaming\Typora\typora-user-images\image-20210809153021548.png)]

从删除的方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zZrBA7Xy-1628725931408)(C:\Users\一路向北\AppData\Roaming\Typora\typora-user-images\image-20210809154233546.png)]

elementData[--size] = null; // clear to let GC do its work
// 这个地方给了一个提示: 不用的数据尽量赋值为null
// 这样有利于垃圾回收器的执行

从indexOf方法来看:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-loEs4blF-1628725931409)(C:\Users\一路向北\AppData\Roaming\Typora\typora-user-images\image-20210809155133298.png)]

判断元素是否相等用的是: equals方法

排序

两个元素进行比较:o1 o2

o1>o2 返回 > 0 的值

01=02 返回 0

01<02 返回 < 0 的值

Collections工具类

Arrays工具类

里面的方法很多,重点掌握排序:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B2VTpJVm-1628725931409)(C:\Users\一路向北\AppData\Roaming\Typora\typora-user-images\image-20210810100717161.png)]

List<Integer> nums = new ArrayList<>();
nums.add(22);
nums.add(1);
nums.add(55);
nums.add(6);
nums.add(7);
nums.add(6);

// 利用Collections里面sort进行排序
Collections.sort(nums);
System.out.println(nums);

List<String> names = new ArrayList<>();
names.add("jack");
names.add("lucy");
names.add("jack2");
Collections.sort(names);

System.out.println(names);

在这里插入图片描述

对象的排序
固定规则-Comparable接口

将排序规则写死, 实现Comparable接口, 并且重写compareTo方法

针对案例中Members可以按照类似的写法去进行排序:

package com.gxa.day17.entity;

public class Member implements Comparable<Member>{

    private String memberName;

    private String memberPwd;

    private Integer memberAge;


    public Member() {
    }

    public Member(String memberName, String memberPwd, Integer memberAge) {
        this.memberName = memberName;
        this.memberPwd = memberPwd;
        this.memberAge = memberAge;
    }

    public String getMemberName() {
        return memberName;
    }

    public void setMemberName(String memberName) {
        this.memberName = memberName;
    }

    public String getMemberPwd() {
        return memberPwd;
    }

    public void setMemberPwd(String memberPwd) {
        this.memberPwd = memberPwd;
    }

    public Integer getMemberAge() {
        return memberAge;
    }

    public void setMemberAge(Integer memberAge) {
        this.memberAge = memberAge;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        Member member = (Member) o;

        return this.memberName.equals(member.memberName) && this.memberAge.equals(member.memberAge);

    }

    @Override
    public String toString() {
        return "Member{" +
                "memberName='" + memberName + '\'' +
                ", memberPwd='" + memberPwd + '\'' +
                ", memberAge=" + memberAge +
                '}';
    }

    @Override
    public int compareTo(Member o) {
        // 按照年龄升序
        // return this.memberAge-o.memberAge;
        // 按照年龄降序
        // return o.memberAge-this.memberAge;

        // 按照名字的升序进行排序
        return this.memberName.compareTo(o.getMemberName());

    }
}

临时规则-Comparator接口

临时规则更灵活, 不需要去修改实体类,随时可以定制比较的规则。

List<Member> members = new ArrayList<>();
members.add(new Member("jack3", "123123", 20));
members.add(new Member("jack1", "123123", 18));
members.add(new Member("jack4", "123123", 21));
members.add(new Member("jack2", "123123", 19));

Collections.sort(members, new Comparator<Member>() {
    @Override
    public int compare(Member o1, Member o2) {
        return o2.getMemberAge()-o1.getMemberAge();
    }
});

以后的排序:

​ redis的排序

排序的场景:

​ 音乐排行榜

​ 阅读量的排行榜

​ 消息列表先后顺序排序

​ 。。。。。

如何判断ArraysList中元素是否相等?

必须要去重写equals方法。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4VomWzPz-1628725931412)(C:\Users\一路向北\AppData\Roaming\Typora\typora-user-images\image-20210809155912992.png)]

Vector

这个类是Java官方都抛弃了,不再使用。

这个类的使用何ArrayList基本一致。

只是效率更低, 线程安全的 =》 效率低, 基本不使用了

LinkedList

就是所谓的“链表”

查询效率偏底, 正常开发不会选择这个类, 优势在于插入数据和删除数据

ArrayList优势在于查询效率高

正常开发的选型: ArrayList > LinkedList > 数组

用这个类最主要的场景是: 实现队列

​ 先进先出

在这里插入图片描述

​连接池: 

​		因为Java去**new**实例的时候,比较耗费资源, 所以发明了一个缓冲池

​		将需要的对象,提前实例化出来, 放入池子中

​		需要用这个对象的时候, 将这个对象从池子中取出来, 不用的时候再放回去

​		需要有一个数据结构: 取数据和存储数据, 利用LinkedList来进行存取数据

​ 只需要掌握: LinkedList中, 如何取出第一个数据, 如何将数据添加到list的左边。

​ 左边进去的方法: add()/addLast()

​ 右边出来的方法: pop()

HashMap***

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rpq3b3vk-1628725931414)(C:\Users\一路向北\AppData\Roaming\Typora\typora-user-images\image-20210810140717392.png)]

主要是用于管理键值对:

​ key=>value

​ 名字 =》 真实的人

​ 身份证号 =》 真实的人

在HashMap中: key是唯一的, 不能重复, 值是可以重复的

构造器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ka9C3hVt-1628725931415)(C:\Users\一路向北\AppData\Roaming\Typora\typora-user-images\image-20210810141123059.png)]

// 无参构建
HashMap<String, String> map1 = new HashMap<>();
// 指定初始容量的构建 => 这种方式最常用
HashMap<String, String> map2 = new HashMap<>(16);
// 指定容量 和 加载因子
HashMap<String, String> map3 = new HashMap<>(16, 0.75f);

常用方法

增加

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9hPYouMh-1628725931416)(C:\Users\一路向北\AppData\Roaming\Typora\typora-user-images\image-20210810141546707.png)]

// 增加数据
map1.put("name", "jack");
map1.put("age", "18");
map1.put("gender", "boy");
map1.put("gender", "girl");
System.out.println(map1);
// 直接增加一个map
map2.putAll(map1);
System.out.println(map2);
删除

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tOibjMoJ-1628725931417)(C:\Users\一路向北\AppData\Roaming\Typora\typora-user-images\image-20210810142102932.png)]

// 删除数据
map2.remove("age");
System.out.println(map2);
修改

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-68ArBKeC-1628725931418)(C:\Users\一路向北\AppData\Roaming\Typora\typora-user-images\image-20210810142301677.png)]

// 只要有对应的key就会去替换
map2.replace("name", "rose");
System.out.println(map2);
// 需要map中存在 key => oldValue这个映射的时候, 才会去替换
map2.replace("name", "jack", "tom");
System.out.println(map2);
查询

在这里插入图片描述

 // 获取数据
String name = map2.get("name");
String gender = map2.get("gender");
System.out.println(name);
System.out.println(gender);
// 获取数据  如果没有返回默认值
String name2 = map2.getOrDefault("name", "tom");
String age1 = map2.get("age");
System.out.println(age1);
String age2 = map2.getOrDefault("age", "20");
System.out.println(name2);
System.out.println(age2);

// 获取大小
int size = map2.size();
System.out.println(size);

// 获取所有的key
Set<String> keys = map2.keySet();
System.out.println(keys);
// 获取所有的值
Collection<String> values = map2.values();
System.out.println(values);
// 是否包含对应的key
System.out.println(map2.containsKey("name"));
// 是否包含对应的value
System.out.println(map2.containsValue("tom"));

遍历

keySet方式
// 获取所有的key
Set<String> keys = map2.keySet();
System.out.println(keys);
for (String key : keys) {
    System.out.println("key:"+key+", value:"+ map2.get(key));
}
Map.entry方式
// 获取 键值对的 entry对象的集合
Set<Map.Entry<String, String>> entries = map2.entrySet();
// 遍历
for (Map.Entry<String, String> entry : entries) {
    System.out.print("key:"+entry.getKey());
    System.out.println("   value:"+entry.getValue());
}

底层

初始容量: 16

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ap1otwJE-1628725931425)(C:\Users\一路向北\AppData\Roaming\Typora\typora-user-images\image-20210810154614848.png)]

有参构造器:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yDlrTXR2-1628725931426)(C:\Users\一路向北\AppData\Roaming\Typora\typora-user-images\image-20210810155113930.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X6H3Dc81-1628725931428)(C:\Users\一路向北\AppData\Roaming\Typora\typora-user-images\image-20210810155319546.png)]

HashMap存储的基本结构图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oy1MzPpd-1628725931429)(C:\Users\一路向北\AppData\Roaming\Typora\typora-user-images\image-20210810161618699.png)]

HashTable

HashTable日常开发基本不用, 效率低, 线程安全的。

HashMap是线程非安全的。

确实是并发场景: 建议使用 ConcurrentHashMap

和HashMap的区别:

  1. HashMap是线程非安全, HashTable线程安全
  2. HashMap的key可以是null, HashTable的key不能为null
HashMap<String, String>  map1 = new HashMap<>(16);
// 不会报空指针
map1.put(null, null);

Hashtable<String, String>  map2 = new Hashtable<>(16);
// 会报空指针
map2.put(null, null);

LinkedHashMap

这个基本没用了, 效率也比较低, 也会去维护前后元素的关系。

TreeMap

主要可以用来排序:

TreeMap<Integer, Integer> treeMap = new TreeMap<>();

treeMap.put(20, 11);
treeMap.put(1, 11);
treeMap.put(3, 11);
treeMap.put(10, 11);
System.out.println(treeMap);

TreeMap<String, Integer> treeMap2 = new TreeMap<>();
treeMap2.put("20", 11);
treeMap2.put("1", 11);
treeMap2.put("3", 11);
treeMap2.put("10", 11);

System.out.println(treeMap2);

HashSet***

用来存放无序唯一的数据。

无序说明没有下标

在这里插入图片描述

构造器

在这里插入图片描述

// 无参构造器
Set<String> set = new HashSet<>();

// 先准备一个List
List<String> names = new ArrayList<>();
names.add("jack");
names.add("rose");
names.add("jack");
System.out.println(names);

// 利用有参构造 -> 去重
Set<String> names2 = new HashSet<>(names);
System.out.println(names2);

常用方法

增加

在这里插入图片描述

// 添加数据
// 相同的数据是不会添加进去的
set.add("1");
set.add("1");
set.add("1");
System.out.println(set);
删除

在这里插入图片描述

// 删除数据
        set.remove("3");
        System.out.println(set);
查询

在这里插入图片描述

// 获取元素的个数
System.out.println(set.size());
// 判断元素是否存在
System.out.println(set.contains("2"));

 // 迭代器
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()){
    System.out.println(iterator.next());
}
// foreach
for (String s : set) {
    System.out.println(s);
}

set判断元素是否存在?

需要同时重写两个方法: equals 和 hashCode

@Override
public boolean equals(Object o) {
    if (this == o) {
        return true;
    }
    if (o == null || getClass() != o.getClass()) {
        return false;
    }
    Member member = (Member) o;

    return this.memberName.equals(member.memberName) && this.memberAge.equals(member.memberAge);

}

@Override
public int hashCode() {
    return Objects.hash(memberName, memberAge);
}

底层

HashSet实际上就是HashMap

HashSet存放的value, 是HashMap中的Key

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TrUR6LN0-1628725931435)(C:\Users\一路向北\AppData\Roaming\Typora\typora-user-images\image-20210811105907797.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mC029Czb-1628725931436)(C:\Users\一路向北\AppData\Roaming\Typora\typora-user-images\image-20210811110001032.png)]

TreeSet

基本用法和HashSet是一样的。

可以用来排序。

TreeSet<Integer> nums = new TreeSet<>();
nums.add(30);
nums.add(1);
nums.add(3);
nums.add(5);
System.out.println(nums);

``

set判断元素是否存在?

需要同时重写两个方法: equals 和 hashCode

@Override
public boolean equals(Object o) {
    if (this == o) {
        return true;
    }
    if (o == null || getClass() != o.getClass()) {
        return false;
    }
    Member member = (Member) o;

    return this.memberName.equals(member.memberName) && this.memberAge.equals(member.memberAge);

}

@Override
public int hashCode() {
    return Objects.hash(memberName, memberAge);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值