当前位置:   article > 正文

【Java数据结构】Map和Set(哈希表详解)_java map set

java map set

Map和set是一种专门用来进行搜索的容器或者数据结构,其搜索的效率与其具体的实例化子类有关。

目录

1. Map

实例化

添加元素(put)

打印

2. Set

实例化

添加元素(add)

打印

3.  小练习

3.1 找出重复的数据(Set练习)

3.2 去重(Set练习)

3.3 统计重复数据出现的次数(Map练习)

4. LeetCode题型训练

4.1 只出现一次的数字

4.2 ⭐⭐复制带随机指针的链表

4.3 宝石与石头

4.4 坏键盘打字

4.5 前K个高频单词(难题)


1. Map

Map是一个接口类,该类没有继承自Collection,该类中存储的是结构的键值对,并且K一定是唯一的,不 能重复。

实例化

  1. Map<String,String> map = new HashMap<>();
  2. HashMap<String,String> map2 = new HashMap<>();

添加元素(put)

  1. map.put("猴哥","孙悟空");
  2. map.put("八戒","猪八戒");
  3. map.put("悟净","沙僧");

打印

  1. import java.util.Set;
  2. //1、直接打印法
  3. System.out.println(map);
  4. //Set打包后再遍历打印法
  5. Set<Map.Entry<String,String>> set = map.entrySet();
  6. for (Map.Entry<String, String> entry : set) {
  7. System.out.println("key:"+entry.getKey()+" Value:"+entry.getValue());
  8. }

2. Set

Set是一个集合类。Set与Map主要的不同有两点:Set是继承自Collection的接口类,Set中只存储了Key。

实例化

  1. import java.util.Set;
  2. Set<Integer> set = new HashSet<>();
  3. HashSet<Integer> set1 = new HashSet<>();

添加元素(add)

和Map一样也是无序的!

  1. set1.add(1);
  2. set1.add(2);
  3. set1.add(3);
  4. set1.add(4);
  5. System.out.println(set1);
  6. set.add("hello");
  7. set.add("hello1");
  8. set.add("hello2");
  9. set.add("hello3");
  10. set.add("hello4");
  11. System.out.println(set);

打印

  1. //1、直接打印
  2. System.out.println(set);
  3. //2、迭代器(不可以遍历Map)
  4. Iterator<String> it = set.iterator();
  5. while (it.hasNext()) {
  6. System.out.println(it.next());
  7. }

3.  小练习

  1. 从10W个数据中,找出第一个重复的数据
  2. 去除10W个数据当中,重复的数据(去重)
  3. 统计重复的数据出现的次数

3.1 找出重复的数据(Set练习)

思路:使用set.contains( ) 判断是否已存在于set中

  1. //判断是否存在set.contains()
  2. public static void main(String[] args) {
  3. int[] array = new int[10];
  4. Random rand = new Random();
  5. for (int i = 0; i < array.length; i++) {
  6. array[i] = rand.nextInt(10);
  7. }
  8. System.out.println(Arrays.toString(array));
  9. HashSet<Integer> set = new HashSet<>();
  10. for (int i = 0; i < array.length; i++) {
  11. if (set.contains(array[i])) {
  12. System.out.println(array[i]);
  13. break;
  14. }
  15. set.add(array[i]);
  16. }
  17. System.out.println(set);
  18. }

3.2 去重(Set练习)

  1. //判断是否存在set.contains()
  2. public static void main(String[] args) {
  3. int[] array = new int[10];
  4. Random rand = new Random();
  5. for (int i = 0; i < array.length; i++) {
  6. array[i] = rand.nextInt(10);
  7. }
  8. System.out.println(Arrays.toString(array));
  9. HashSet<Integer> set = new HashSet<>();
  10. for (int i = 0; i < array.length; i++) {
  11. set.add(array[i]);
  12. }
  13. System.out.println(set);
  14. }

3.3 统计重复数据出现的次数(Map练习)

使用map.containsmap.get() == null 都可以用来判断是否已经存在。

  1. public class Test {
  2. public static void main(String[] args) {
  3. int[] array = new int[10];
  4. Random rand = new Random();
  5. for (int i = 0; i < array.length; i++) {
  6. array[i] = rand.nextInt(5);
  7. }
  8. HashMap<Integer,Integer> map = new HashMap<>();
  9. //判断数组的数据 是否再map中 没有就是1,有的话就value+1
  10. for (int i = 0; i < array.length; i++) {
  11. /*if (map.containsKey(array[i])) {
  12. int val = map.get(array[i]);
  13. map.put(array[i], val+1);
  14. } else {
  15. map.put(array[i], 1);
  16. }*/
  17. if (map.get(array[i] == null)) {
  18. map.put(array[i],1);
  19. } else {
  20. int val = map.get(array[i]);
  21. map.put(array[i],val+1);
  22. }
  23. }
  24. //打印
  25. for (Map.Entry<Integer,Integer> entry: map.entrySet()) {
  26. System.out.println("关键字 "+entry.getKey()+" 次数"+entry.getValue());
  27. }
  28. }
  29. }

4. LeetCode题型训练

4.1 只出现一次的数字

136. 只出现一次的数字 - 力扣(LeetCode) (leetcode-cn.com)

常规最优解题法(异或):

  1. class Solution {
  2. public int singleNumber(int[] nums) {
  3. int sum = 0;
  4. for (int i = 0; i < nums.length; i++) {
  5. sum ^= nums[i];
  6. }
  7. return sum;
  8. }
  9. }

使用Set:

  1. class Solution {
  2. public int singleNumber(int[] nums) {
  3. HashSet<Integer> set = new HashSet<>();
  4. for (int val : nums) {
  5. if (set.contains(val)) {
  6. set.remove(val);
  7. } else {
  8. set.add(val);
  9. }
  10. }
  11. for (int val : nums) {
  12. if (set.contains(val)) {
  13. return val;
  14. }
  15. }
  16. return -1;
  17. }
  18. }

4.2 ⭐⭐复制带随机指针的链表

138. 复制带随机指针的链表 - 力扣(LeetCode) (leetcode-cn.com)

  1. class Solution {
  2. public Node copyRandomList(Node head) {
  3. HashMap<Node,Node> map = new HashMap<>();
  4. Node cur = head;
  5. while (cur != null) {
  6. Node node = new Node(cur.val);
  7. map.put(cur,node);
  8. cur = cur.next;
  9. }
  10. cur = head;
  11. while (cur != null) {
  12. map.get(cur).next = map.get(cur.next);
  13. map.get(cur).random = map.get(cur.random);
  14. cur = cur.next;
  15. }
  16. return map.get(head);
  17. }
  18. }

4.3 宝石与石头

771. 宝石与石头 - 力扣(LeetCode) (leetcode-cn.com)

  1. class Solution {
  2. public int numJewelsInStones(String jewels, String stones) {
  3. HashSet<Character> set = new HashSet<>();
  4. for (int i = 0; i < jewels.length(); i++) {
  5. char ch = jewels.charAt(i);
  6. set.add(ch);
  7. }
  8. int count = 0;
  9. for (int i = 0; i < stones.length(); i++) {
  10. char ch = stones.charAt(i);
  11. if (set.contains(ch)) {
  12. count++;
  13. }
  14. }
  15. return count;
  16. }
  17. }

4.4 坏键盘打字

旧键盘 (20)__牛客网 (nowcoder.com)

思路:

  1. 把str1当中的每个字符,转换成大写的,然后放到集合当中(char[ ]  ch=str1.toUpperCase().toCharArray() ;
  2. 遍历str1,每个字符仍然要是大写,和集合当中的元素去比较,没有就输出
  1. import java.util.*;
  2. public class Main {
  3. public static void func(String str1, String str2) {
  4. HashSet<Character> set = new HashSet<>();
  5. //把打印出来的东西放进set
  6. for (char ch : str2.toUpperCase().toCharArray()) {
  7. set.add(ch);
  8. }
  9. for (char ch : str1.toUpperCase().toCharArray()) {
  10. if (!set.contains(ch)) {
  11. System.out.print(ch);
  12. set.add(ch);
  13. }
  14. }
  15. }
  16. public static void main(String[] args) {
  17. Scanner sc = new Scanner(System.in);
  18. String str1 = sc.nextLine();
  19. String str2 = sc.nextLine();
  20. func(str1,str2);
  21. }
  22. }

4.5 前K个高频单词(难题)

692. 前K个高频单词 - 力扣(LeetCode) (leetcode-cn.com)

思路:

  1. 统计字符串当中每个单词出现的次数(HashMap)
  2. 定义一个小根堆,设置其比较方式是根据每个单词出现的次数进行比较
  3. 开始遍历map,拿到每一个entry
  1. class Solution {
  2. public List<String> topKFrequent(String[] words, int k) {
  3. //1、统计单词出现的次数 存放在map当中
  4. HashMap<String,Integer> map = new HashMap<>();
  5. for (String s : words) {
  6. if (map.get(s) == null) {
  7. map.put(s,1);
  8. } else {
  9. int val = map.get(s);//原来这个单词出现的次数
  10. map.put(s,val+1);
  11. }
  12. }
  13. //定义一个小根堆,因为我们找的是出现频率高的,所以小根堆的比较方式是根据每个单词出现的次数进行比较
  14. PriorityQueue<Map.Entry<String,Integer>> minHeap = new PriorityQueue<>(new Comparator<Map.Entry<String,Integer>>() {
  15. @Override
  16. public int compare(Map.Entry<String,Integer> o1, Map.Entry<String,Integer> o2) {
  17. if(o1.getValue().compareTo(o2.getValue()) == 0) {
  18. return o2.getKey().compareTo(o1.getKey());
  19. }
  20. return o1.getValue()-o2.getValue();
  21. }
  22. });
  23. //3、开始遍历map,拿到每一个entry
  24. for (Map.Entry<String,Integer> entry : map.entrySet()) {
  25. if (minHeap.size() < k ) {
  26. minHeap.offer(entry);
  27. } else {
  28. Map.Entry<String,Integer> top = minHeap.peek();
  29. if (top != null) {
  30. if (top.getValue().compareTo(entry.getValue()) == 0) {
  31. if (entry.getKey().compareTo(top.getKey()) < 0) {
  32. minHeap.poll();
  33. minHeap.offer(entry);
  34. }
  35. } else {
  36. if (entry.getValue().compareTo(top.getValue()) > 0) {
  37. minHeap.poll();
  38. minHeap.offer(entry);
  39. }
  40. }
  41. }
  42. }
  43. }
  44. //4、小堆弹出信息
  45. List<String> ret = new ArrayList<>();
  46. for (int i = 0; i < k; i++) {
  47. Map.Entry<String,Integer> top = minHeap.poll();
  48. if (top != null) {
  49. ret.add(top.getKey());
  50. }
  51. }
  52. Collections.reverse(ret);
  53. return ret;
  54. }
  55. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/990683
推荐阅读
相关标签
  

闽ICP备14008679号