Java20--集合2(Set+HashSet)+Map(HashMap)+Collections工具类

1 Set接口

1.1 概述

一个不包含重复元素的 collection。

数据无序(因为set集合没有下标)。

由于集合中的元素不可以重复。常用于给数据去重。

1.2 特点

Ø HashSet:底层是哈希表,包装了HashMap,相当于向HashSet中存入数据时,会把数据作为K,存入内部的HashMap中。当然K仍然不许重复。

Ø TreeSet:底层就是TreeMap,也是红黑树的形式,便于查找数据。

Ø HashMap实现中,当哈希值相同的对象,会在同一个hash值的位置存储不同属性的数据。
在这里插入图片描述

1.3 常用方法

boolean add(E e):添加元素。

boolean addAll(Collection  c):把小集合添加到大集合中 。

boolean contains(Object o) : 如果此 collection 包含指定的元素,则返回 true。

boolean isEmpty() :如果此 collection 没有元素,则返回 true。

Iterator<E> iterator():返回在此 collection 的元素上进行迭代的迭代器。

boolean remove(Object o) :从此 collection 中移除指定元素的单个实例。

int size() :返回此 collection 中的元素数。

Objec[] toArray():返回对象数组

1.4 练习1:测试常用方法

package seday12;

import java.util.HashMap;

import java.util.HashSet;

import java.util.Iterator;

import java.util.Map;

import java.util.Map.Entry;

import java.util.Set;

public class Test0_Map {

       public static void main(String[] args) {

              Set set = new HashSet ();

              set.add("hello");

              set.add("b");

              set.add("a");

              set.add("world");

              set.add("b");

              //不存重复元素,元素无序

              System.out.println(set);

              //迭代器

              Iterator it = set.iterator();

              while(it.hasNext()) {

                     System.out.println(it.next());
              }
       }
}

2 HashSet

2.1 概述

此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。

2.2 练习1:获取HashSet里的元素

package seday12;

import java.util.HashMap;

import java.util.HashSet;

import java.util.Iterator;

import java.util.Map;

import java.util.Map.Entry;

import java.util.Set;

public class Test0_Map {

    public static void main(String[] args) {

       HashSet set = new HashSet();

       set.add("a");

       set.add("e");

       set.add("b");

       set.add("a");

       set.add("b");

       System.out.println(set);//无序,不重复

       Iterator it = set.iterator();

       while(it.hasNext()) {

           System.out.println(it.next());

       }
    }

}

2.3 练习2:Set存储属性值相同的对象

需求:我们仍然假设相同属性的两个人是同一个人

1、按照以前的经验,这种需求只需要重写equals()方法就可以实现。

2、但是我们提供以后,equals()根本就没有执行。问题出现在新增功能。

3、查找新增的源码发现,其实在添加时只是计算对象的hash值。

4、由于每次创建对象时hash值都不一样,所以每次都会当做新对象存起来。

5、所以,现在我们必须保证两个对象的hash值相同,重写hashCode()。
在这里插入图片描述

package seday12;

 

import java.util.HashMap;

import java.util.HashSet;

import java.util.Iterator;

import java.util.Map;

import java.util.Map.Entry;

import java.util.Set;

 

public class Test0_Map {

    public static void main(String[] args) {

       HashSet set = new HashSet();

       //创建元素

       Student s1 = new Student("西门庆",20);

       Student s2 = new Student("武大郎",19);

       Student s3 = new Student("潘金莲",21);

       Student s4 = new Student("小龙女",23);

       Student s5 = new Student("武大郎",19);

       Student s6 = new Student("潘金莲",21);

       //添加时,新元素会和老元素比

       set.add(s1);

       set.add(s2);

       set.add(s3);

       set.add(s4);

       //默认:添加时查找对象的hash值,没有查到就存起来

       //所以必须让hash值一致才可以

       set.add(s5);

       set.add(s6);

       //问题1:属性相同时还是认为是两个对象...

       System.out.println(set);

      

//     遍历

       Iterator it = set.iterator();

       while(it.hasNext()) {

           System.out.println(it.next());

       }

      

    }

}

 

创建Student类

package seday12;

 

public class Student {

    private String name;

    private int age;

   

    public Student(String name, int age) {

       this.name = name;

       this.age = age;

    }

    public Student() {

    }

    public String getName() {

       return name;

    }

    public void setName(String name) {

       this.name = name;

    }

    public int getAge() {

       return age;

    }

    public void setAge(int age) {

       this.age = age;

    }

   

    @Override

    public String toString() {

       return "Student [name=" + name + ", age=" + age + "]";

    }

   

    //需求:属性值都一样就看做是同一个对象

    @Override

    public boolean equals(Object obj) {

       if (this == obj)

           return true;

       if (obj == null)

           return false;

       if (getClass() != obj.getClass())

           return false;

       Student other = (Student) obj;

       if (age != other.age)

           return false;

       if (name == null) {

           if (other.name != null)

              return false;

       } else if (!name.equals(other.name))

           return false;

       return true;

    }

   

    //HashSet默认:添加时查找对象的hash值,没有查到就存起来

    //所以必须让hash值一致才可以

//必须用算法,不然的话,hash值相同时会挂一串

    public int hashCode() {

       //return 0;//效率低

//让基本类型*31,引用类型就用自己的hash值

       final int prime = 31;

       int result = 1;

       result = prime * result + age;

       result = prime * result + ((name == null) ? 0 : name.hashCode());

       return result;

    }

   

}

3 Map接口

3.1 概述

java.util接口 Map<K,V>

类型参数: K - 此映射所维护的键的类型V - 映射值的类型。

也叫哈希表、散列表。常用于存 键值对 结构的数据。其中的键不能重复,值可以重复.
在这里插入图片描述

3.2 特点

Ø 可以根据键 提取对应的值

Ø 键不允许重复,如果重复值会被覆盖

Ø 存放的都是无序数据

Ø 初始容量是16,默认的加载因子是0.75
在这里插入图片描述

3.3 继承结构

在这里插入图片描述

3.4 常用方法

void clear()

          从此映射中移除所有映射关系(可选操作)。

 boolean containsKey(Object key)

          如果此映射包含指定键的映射关系,则返回 true。

 boolean containsValue(Object value)

          如果此映射将一个或多个键映射到指定值,则返回 true。

 V get(Object key)

          返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。

 boolean isEmpty()

          如果此映射未包含键-值映射关系,则返回 true。

 V put(K key, V value)

          将指定的值与此映射中的指定键关联(可选操作)。

 void putAll(Map<? extends K,? extends V> m)

          从指定映射中将所有映射关系复制到此映射中(可选操作)。

 V remove(Object key)

          如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。

 int size()

          返回此映射中的键-值映射关系数。

Set<Map.Entry<K,V>> entrySet()

          返回此映射所包含的映射关系的 Set 视图。

3.5 练习1:测试常用方法

package seday12;

 

import java.util.HashMap;

import java.util.Map;

import java.util.Map.Entry;

import java.util.Set;

 

 

public class Test0_Map {

       public static void main(String[] args) {

              Map map = new HashMap ();

              map.put("001", "钢铁侠");

              map.put("002", "蜘蛛侠");

              map.put("003", "绿巨人");

              map.put("004", "灭霸");

              map.put("005", "美国队长");

              map.put("005", "凤姐");

              System.out.println(map.containsKey("001"));

              System.out.println(map.containsValue("美国队长"));

              System.out.println(map.isEmpty());

              System.out.println(map.get("003"));

              System.out.println(map.remove("001"));

              System.out.println(map.size());

              Map map2 = new HashMap ();

              map2.put("999", "刘德华");

map.put(null,null);//可以存入键为null,值也null的数据

 

              map.putAll(map2);

              System.out.println(map);

             

              //keySet()返回键的set集合,把map的key形成set集合

              Set set = map.keySet();

              System.out.println(set);

             

             

              //map集合的遍历,

              //方式1:keySet():把map中的可以放入set集合

              //遍历方式1:keySet ()

Set set = m.keySet();

              Iterator it = set.iterator();

              while(it.hasNext()) {

                     String key = (String) it.next();

                     String val = (String) m.get(key);

                     System.out.println(key+"="+val);

              }

      

              //遍历方式2:entrySet ()

Set set2 = m.entrySet();

              Iterator it2 = set2.iterator();

              while(it2.hasNext()) {

                     Entry en = (Entry) it2.next();

                     String key = (String) en.getKey();

                     String value = (String) en.getValue();

                     System.out.println(key+"=="+value);

              }

             

       }

}

4 HashMap

Ø HashMap的键要同时重写hashCode()和equals()

hashCode()用来判断确定hash值是否相同

equals()用来判断属性的值是否相同

– equals()判断数据如果相等,hashCode()必须相同

– equals()判断数据如果不等,hashCode()尽量不同

4.1 概述

基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。

HashMap底层是一个Entry数组,当存放数据时会根据hash算法计算数据的存放位置。算法:hash(key)%n,n就是数组的长度。

当计算的位置没有数据时,就直接存放,当计算的位置有数据时也就是发生hash冲突的时候/hash碰撞时,采用链表的方式来解决的,在对应的数组位置存放链表的头结点。对链表而言,新加入的节点会从头结点加入。
在这里插入图片描述

4.2 练习1:读取HashMap的数据

package seday12;

 

import java.util.HashMap;

import java.util.Iterator;

import java.util.Map;

import java.util.Map.Entry;

import java.util.Set;

 

public class Test0_Map {

       public static void main(String[] args) {

              HashMap map = new HashMap ();

              map.put(100, "刘德华");

              map.put(101, "梁朝伟");

              map.put(102, "古天乐");

              map.put(103, "周润发");

 

//遍历方式1:keySet ()

Set set = m.keySet();

              Iterator it = set.iterator();

              while(it.hasNext()) {

                     String key = (String) it.next();

                     String val = (String) m.get(key);

                     System.out.println(key+"="+val);

              }

      

              //遍历方式2:entrySet ()

Set set2 = m.entrySet();

              Iterator it2 = set2.iterator();

              while(it2.hasNext()) {

                     Entry en = (Entry) it2.next();

                     String key = (String) en.getKey();

                     String value = (String) en.getValue();

                     System.out.println(key+"=="+value);

              }

       }

}

4.3 练习2:字符串中的字符统计

接收用户输入的一串字符串,统计出现的每个字符的个数

package seday12;

import java.util.HashMap;

import java.util.Scanner;

public class Test2_Count {

       public static void main(String[] args) {

              //abacbcda

              String s = new Scanner(System.in).nextLine();

             

              //a 1  b 2  c 1

              HashMap<Character,Integer> map = new HashMap<>();

              //遍历字符串获取每个字符

              for(int i = 0;i<s.length();i++) {

                     //1,取出字符串中的每个字符

                     char c = s.charAt(i);

                    

                     //拿着字符查个数

                     Integer count = map.get(c);

 

                     //如果取出来是null,就存1,

                     if(count==null) {

                            map.put(c, 1);

                     }else {

                            //如果取出来有值,计数加1

                            map.put(c,count+1);

                     }

              }

              System.out.println(map);

       }

}

5 Collections工具类

5.1 常用方法

Collections.sort(List<> list):根据元素的自然顺序 对指定列表按升序进行排序。

Collections.max():根据元素的自然顺序,返回给定 collection 的最大元素。

Collections.min():根据元素的自然顺序 返回给定 collection 的最小元素。

Collections.swap(List,i,j):在指定列表的指定位置处交换元素。

Collections.addAll():

5.2 测试

package seday12;

import java.util.ArrayList;

import java.util.Collections;

import java.util.Comparator;

import java.util.List;

public class Test4_Collections {

       public static void main(String[] args) {

              List<String> list = new ArrayList();

             

              //添加多个元素

              Collections.addAll(list,

                            "3","30","23","15","29","12","26");

             

              //元素排序

              Collections.sort(list);

          //默认是字符顺序:[12,15,23,26,29, 3, 30]

              System.out.println(list);

             

              //自己定义比较方式

              Collections.sort(list, new Comparator<String>() {

                     //自定义比较器,sort()自动调用

                     @Override

                     public int compare(String o1, String o2) {

                            //把字符串转成int比大小

                            int a = Integer.parseInt(o1);

                            int b = Integer.parseInt(o2);

//o1大是正数,o1小是负数,相等是0

                            return a-b;

                     }

              });

              System.out.println(list);

       }

}

6 拓展

6.1 集合和数组的区别

6.2 HashMap实现原理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值