Java 常用Set集合和常用Map集合

目录

常用Set集合

Set集合的特点

​ Set接口下的集合都会有以下特点

  • 不能存储重复元素
  • 没有索引

HashSet

HashSet集合的特点

  • 底层数据结构是哈希表
  • 存储元素的顺序和遍历获取出来的顺序可能不一致
  • 没有索引
  • 集合中不能存储重复元素

创建对象

HashSet<元素数据类型> set = new HashSet<>();
public static void main(String[] args) {
    HashSet<String> set = new HashSet<>();
}

常用方法

方法解释
boolean add(E e)添加元素,如果元素添加不成功 返回值代表是否添加成功
boolean remove(Object o)删除元素 ,返回值代表删除元素是否成功
boolean contains(Object o)判断元素是否存在
int size()获取集合的大小
public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        //添加元素
        boolean f = set.add("愚");
        set.add("生");
        set.add("浅");
        set.add("末");
        System.out.println(f);
    }

我们打断点调试一下:

可以看到愚生浅末四个字符已经装入set,且f为true证明添加成功。

我们再试试删除:

public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        //添加元素
        set.add("愚");
        set.add("生");
        set.add("浅");
        set.add("末");
        boolean f = set.remove("生");
    }

可以看到set已经没有生了,且f为true代表删除成功。

判断是否存在:

public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        //添加元素
        set.add("愚");
        set.add("生");
        set.add("浅");
        set.add("末");
        boolean f = set.contains("末");
    }

末是存在于set的,所以返回值为true。

获取集合的大小:

public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        //添加元素
        set.add("愚");
        set.add("生");
        set.add("浅");
        set.add("末");
         //获取集合的大小
        int size = set.size();

添加了愚生浅末四个字符,所以可以得到size是4.

遍历

1.转换为数组遍历

public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        set.add("愚");
        set.add("生");
        set.add("浅");
        set.add("末");
        String[] strings = set.toArray(new String[0]);
        for (int i = 0; i < strings.length; i++) {
            System.out.println(strings[i]);
        }
    }

结果:

前面说过:存储元素的顺序和遍历获取出来的顺序可能不一致。

2.使用迭代器遍历

public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        set.add("愚");
        set.add("生");
        set.add("浅");
        set.add("末");
        Iterator<String> it = set.iterator();
        while (it.hasNext()){
            String s = it.next();
            System.out.println(s);
        }
    }

结果:

3.foreach遍历

public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        set.add("愚");
        set.add("生");
        set.add("浅");
        set.add("末");
        for (String s : set) {
            System.out.println(s);
        }
    }

结果:

常用Map集合

Map集合的概述

Map接口是双列集合的顶层接口,下面是Map接口的定义

interface Map<K,V>  K:键的类型;V:值的类型

​ 存储的数据必须包含key和value。

​ key和value在Map集合中是一一对应的关系。一个key对应一个value。

​ key在map集合中是不会重复的。

HashMap

HashMap集合的特点

  • 底层数据结构是哈希表
  • 存储元素的顺序和遍历获取出来的顺序可能不一致
  • key不会重复

创建对象

HashMap<key的数据类型,value的数据类型> map = new HashMap<>();

例如:

public static void main(String[] args) {
        HashMap<String,String> map = new HashMap<>();
        HashMap<String,Integer> map = new HashMap<>();
    }

常用方法

方法解释
V put(K key, V value)添加元素,如果key不存在就添加,如果key
V get(Object key)根据key获取对应的value值返回。如果key不存在就返回null
V remove(Object key)根据key删除map中对应的键值对。并且把删除的value返回
boolean containsKey(Object key)判断key是否存在
int size()集合中键值对的对数
void clear()清空集合中的所有键值对
public static void main(String[] args) {
        HashMap<String,String> map = new HashMap<>();
//        map.put()
        //添加元素
        map.put("name", "愷龍");
        map.put("age", "20");
        String v = map.put("name", "愚生浅末");//将原来的愷龍替换为愚生浅末
        String name = map.get("name");//获取名字:愷龍
        String age = map.get("age");//获取age:20
        //删除元素
        String delV = map.remove("age");//返回值为20
        //判断key是否存在
        if(map.containsKey("name")){
            String agea = map.get("name");//null
            System.out.println(agea.length());
        }
        //size
        int size = map.size();
        map.clear();
    }

遍历

1.使用entrySet遍历

​ map集合的entrySet方法可以获取一个Set集合,集合中存放的是Entry对象,一个Entry对象相当于一个键值对。我们可以遍历set集合拿到Entry对象,然后获取出里面的键和值。

使用迭代器遍历entrySet

public static void main(String[] args) {
        HashMap<String,String> map = new HashMap<>();
        map.put("name","愷龍");
        map.put("age","20");
        Set<Map.Entry<String, String>> entries = map.entrySet();
        //使用迭代器遍历entrySet
        Iterator<Map.Entry<String, String>> it = entries.iterator();
        while (it.hasNext()){
            Map.Entry<String, String> entry = it.next();
            System.out.println(entry.getKey()+"="+entry.getValue());
        }
    }

结果:

使用foreach遍历entrySet

public static void main(String[] args) {
        HashMap<String,String> map = new HashMap<>();
        map.put("name","愷龍");
        map.put("age","20");
        Set<Map.Entry<String, String>> entries = map.entrySet();
        //使用foreach遍历entrySet
        for (Map.Entry<String, String> entry : entries) {
            System.out.println(entry.getKey()+"="+entry.getValue());
        }
    }

结果:

2.使用keySet遍历

​ map集合的keySet方法可以获取一个Set集合,集合中存放的是所有的key。我们可以遍历set集合拿到key对象,然后通过key获取对应的value。

public static void main(String[] args) {
        HashMap<String,String> map = new HashMap<>();
        map.put("name","愷龍");
        map.put("age","20");
        Set<String> keys = map.keySet();
        for (String key : keys) {
            System.out.println(key+"="+map.get(key));
        }
    }

结果:

HashMap的key去重原理

​ HashMap在添加元素的时候会判断集合中是否有key和本次存入的key相同。判断的时候主要是通过hashCode方法和equals方法来进行判断的。hashCode相同,并且equals判断也相同就会认为是同一个key。

​ 所以如果我们要存储到HashMap中的key是一个自定义的类型。就需要根据情况判断下是否需要重写下hashCode方法和equals方法。重写的时候使用IDEA的提示即可。

public class Student {
    private int age;
    private String name;
    public String getName(){
        return name = this.name;
    }
    public void setName(String name){
        this.name = name;
    }
    public int getAge(){
        return age = this.age;
    }
    public void setAge(int age){
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name, student.name);
    }

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

​ 注意:HashSet存储数据其实也是使用了HashMap。所以如果往HashSet中存储自定义对象也要看情况是否需要重写hashCode方法和equals方法。

Java 中的 Set 集合 Map 集合存在多方面差异。 ### 基本概念 - **Set 集合**:是一个无序集合,元素不可重复,重复元素会被覆盖掉,集合中的对象不按特定的方式排序,只是简单地把对象加入集合中。元素在 Set 中的位置由该元素的 HashCode 决定,其位置是固定的,加入 Set 的 Object 必须定义 equals() 方法。Set 只能用迭代器遍历,因为它是无序的 [^2]。 - **Map 集合**:集合中存储的是键值对,键不能重复,值可以重复。根据键可以得到值,对 map 集合遍历时先得到键的 set 集合,对该 set 集合进行遍历,从而得到相应的值 [^2]。 ### 接口继承关系 Set 接口类继承 Collection 接口,而 Map 则不继承 Collection 接口 [^2]。 ### 元素特性 - **Set 集合**:只存储单个元素,关注元素本身的唯一性 [^2]。 - **Map 集合**:存储键值对,关注键的唯一性以及键值的映射关系 [^2]。 ### 常用实现类及特点 - **Set 集合**:常用具体实现有 HashSet TreeSet 类。HashSet 能快速定位一个元素,但放入其中的对象需要实现 hashCode() 方法;TreeSet 则将放入其中的元素按序存放,要求放入其中的对象是可排序的,需要实现 Comparable 接口或使用 Comparator 接口 [^4]。 - **Map 集合**:常见实现类如 HashMap、TreeMap 等。HashMap 基于哈希表实现,允许使用 null 键 null 值,不保证元素顺序;TreeMap 基于红黑树实现,会根据键的自然顺序或指定的比较器对键进行排序 [^2]。 ### 操作效率 - **Set 集合**:检索元素效率较低,删除插入效率高,因为删除插入不会引起元素的位置变化 [^2]。 - **Map 集合**:根据键查找值的效率较高,插入删除操作在一般情况下也有较好的性能,但在需要维护键的顺序时(如 TreeMap),可能会有额外的开销 [^2]。 ### 遍历方式 - **Set 集合**:只能使用迭代器进行遍历 [^2]。 - **Map 集合**:先得到键的 set 集合,对该 set 集合进行遍历,进而得到相应的值 [^2]。示例代码如下: ```java import java.util.HashMap; import java.util.Map; import java.util.Set; public class MapTraversal { public static void main(String[] args) { Map<String, Integer> map = new HashMap<>(); map.put("apple", 1); map.put("banana", 2); map.put("cherry", 3); Set<String> set = map.keySet(); for (String key : set) { System.out.println(key + "\t" + map.get(key)); } } } ``` ### 集合视角 Map 虽然不是真正意义上的集合,但提供了三种“集合视角”,可将其内容看作 key 的集合、value 的集合以及 key - value 映射的集合,方便像操作集合一样操作它 [^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值