集合Set与Map

目录

 

HashSet

hashcode方法:

equals方法:

比较器

1.内部比较器

外部比较器

1、定义一个实现接口的类

2.使用匿名内部类方式 ----

3.使用Lmabda表达式

HashMap


HashSet

底层结构:哈希表(数组+链表+红黑树) ------------->由HashMap维护

优点:集数组,链表,红黑树为一体,所以综合能力较好,查询,增删效率较高

缺点:实现了Set接口,所以无序

应用场景:实现存储不同的数据,对查询,增删效率要求较高的时候建议使用HashSet

无新增接口

去重:在需要存储的自定义引用数据类型中重写hashcode与equals方法

hashcode方法:

    //存储Person对象
    hash.add(new Person("张三",18));
    hash.add(new Person("李四",17));
    hash.add(new Person("张三",18));
​
    System.out.println(hash);
    System.out.println(new Person("张三",18).hashCode());
    System.out.println(new Person("张三",18).hashCode());
}
    

equals方法:

//省略构造器,set/get方法,toString方法
//重写equals与hashCode
@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(name, age);
}

比较器

1.内部比较器

又叫自然排序,是定义在类型内部的比较方式,实现了 java.lang.Comparable 接口

使用方法:实现Comparable接口,重写compareTo(T o)方法

方法内部指定比较规则: compareTo 返回值 int 类型 T1.compareTo(T2) -> 0: 相等 整数:T1>T2 负数:T1<T2

优缺点:

优点: 默认比较方式,定义在类的内部

缺点: 固定,硬编码,不够灵活

代码:以上面的Person为例

class Person implements Comparable<Person>{ ...... ...... //重写compareTo方法,以年龄为例 public int compareTo(Student o) { return this.getAge.-o.getAge(); } }

外部比较器

又叫订制排序,是一个定义在一个类型(要比较的对象数据的类型)的外部的比较方式

使用方法:实现 java.util.Comparator<T>接口,重写compare(T t1, T t2)

定义比较规则 返回值: 0: 相等 正数:T1>T2 负数:T1<T2

//三种方式

1、定义一个实现接口的类

class Demo implements Comparator<Person>{ @Override public int compare(Person o1, Person o2) { //return o2.getAge()-o1.getAge(); 使用年龄比较 return o1.getName().compareTo(o2.getName()); //使用姓名比较 } }

2.使用匿名内部类方式 ----

----> 简化简化没有类本身作用的实现类 Comparator<Person> com = new Comparator<Person>() { @Override public int compare(Person o1, Person o2) { return o1.getAge()-o2.getAge(); } };

3.使用Lmabda表达式

com = (x,y)->y.getAge()-x.getAge(); Arrays.sort(数组) 默认升序排序,

使用Arrays.sort(数组)比较自定义引用数据类型的数组

需要用到比较器才能进行比较

public static void main(String[] args) {
    //数组
    Person[] arr = {
        new Person("zhangsan",18),
        new Person("lisa",16),
        new Person("wangwu",19),
        new Person("赵六",19)
    };
​
    System.out.println(Arrays.toString(arr));
    //使用默认比较规则   Person类中的compareTo方法
    Arrays.sort(arr);
    //使用参数2指定的外部比较规则
    Arrays.sort(arr, (t1,t2)->t1.getAge()-t2.getAge());
    System.out.println(Arrays.toString(arr));
}

Map<k,v> 集合中的元素由键值对k-v组成 k(key): 可以为任意引用数据类型数据 --> Set 无序不可重复 v(value): 可以为任意引用数据类型数据 --> Collection 可重复无序 一个key只能对应一个value->映射关系 可以根据key操作value,Map的无序与去重 由key决定

Map集合的一些常用方法: public static void main(String[] args) { //创建Map集合 Map<Integer,String> map = new HashMap<>();

V put(K key, V value) 将指定的值与此映射中的指定键相关联(可选操作)。
V get(Object key) 返回指定键映射到的值,如果此映射不包含键的映射,则返回 null 。
boolean containsKey(Object key) 如果此映射包含指定键的映射,则返回 true 。
boolean containsValue(Object value) 如果此映射将一个或多个键映射到指定值,则返回 true 。
V remove(Object key) 如果存在,则从该映射中移除键的映射(可选操作)。

Map集合的遍历方式 keySet 获取所有的key值,返回一个set集合 values() 获取map集合中所有键值对的value,返回一个Collection集合 entrySet() 获取所有的键值对->Map.Entry 类型->表示一个键值对 public static void main(String[] args) { //创建Map集合 Map<Integer,String> map = new HashMap<>(); map.put(1001,"zhangsan"); map.put(1002,"lisi"); map.put(1003,"wangwu");

//1.keySet
Set<Integer> keys= map.keySet();
for(Integer i:keys){
    System.out.println(i+"-->"+map.get(i));
}
​
//2.values()
Collection<String> col = map.values();
for(String s:col){
    System.out.println(s);
}
​
//3)entrySet
Set<Map.Entry<Integer,String>> set = map.entrySet();
Iterator<Map.Entry<Integer,String>> it = set.iterator();
for(;it.hasNext();){
    Map.Entry entry = it.next();
    System.out.println(entry.getKey()+"-->"+entry.getValue());
}
}

HashMap

底层结构: 哈希表(数组+链表+红黑树)

特点: 查询,增删效率较高

新增内容: 没有新增功能

遍历方式: 与Map接口相同

扩容问题: 初始容量16,newCap = oldCap << 1 数组每次扩容原容量的两倍

DEFAULT_INITIAL_CAPACITY 初始容量 16

DEFAULT_LOAD_FACTOR : 默认加载因子 0.75

threshold : 扩容临界值 DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY

上一篇:Codeforces 1132C - Painting the Fence - [前缀和优化]


下一篇:Java自学习day10-封装类练习-用setAge()设置人的合法年龄(0~130),用getAge()返回人的年龄。