java、Set集合和Map集合

Bertha 。 2022-03-31 18:58 540阅读 0赞

-————— android培训、java培训、java学习型技术博客、期待与您交流! ——————

一、Set集合
1、什么是Set集合?
Set是Collection的一种,即Set是Collection的子接口。
2、Set有什么特性:
1.它不要求顺序,无重复元素
2.没索引
3、Set有五种实现类:
1.HashSet 2.TreeSet 3.LinkedHashSet
4、HashSet TreeSet LinkedHashSet它们分别有什么特征?
HashSet特征:
1.它的底层是用hash表数据结构,线程不同步,无序,高效。
2.HashSet集合保证了元素的唯一性:通过元素的HasCode方法和equals方法完成的。
3.当元素的HashCode值相同时,才继续判断元素的equals值是否是否为true。如果为true,那么视为相同元素,不存储。如果为false,那么存储。
4.如果HashCode不同,那么不比较equas方法,直接存储,从而直接提高对象比较的速度。
HashCode实例:

  1. import java.util.HashSet;
  2. import java.util.Iterator;
  3. import java.util.Set;
  4. public class ComparableDemo {
  5. /**
  6. * @param args
  7. */
  8. public static void main(String[] args) {
  9. 创建一个Set集合的引用指向HashSet的对象
  10. Set se = new HashSet();
  11. //实例化1
  12. Person p1 = new Person("ZhangSan", 23, "male");
  13. //实例化2
  14. Person p2 = new Person("LiSi", 32, "female");
  15. //实例化3
  16. Person p3 = new Person("WangWu", 28, "male");
  17. //实例化4
  18. Person p4 = new Person("ZhaoLiu", 23, "female");
  19. //实例化5
  20. Person p5 = new Person("ZhangSan", 23, "male");
  21. //将实例化对象添加进集合中
  22. se.add(p1);
  23. se.add(p2);
  24. se.add(p3);
  25. se.add(p4);
  26. se.add(p5);
  27. //迭代集合中的元素
  28. Iterator<Person> it = se.iterator();
  29. //判断集合中是否存在元素
  30. while (it.hasNext()) {
  31. //迭代下一个元素
  32. Person per = it.next();
  33. //打印元素
  34. System.out.println(per);
  35. }
  36. }
  37. }
  38. package SetDemo;
  39. //创建一个实体类
  40. public class Person {
  41. private String name;
  42. private int age;
  43. private String sex;
  44. public Person(String name, int age, String sex) {
  45. super();
  46. this.name = name;
  47. this.age = age;
  48. this.sex = sex;
  49. }
  50. public Person() {
  51. super();
  52. }
  53. public String getName() {
  54. return name;
  55. }
  56. public void setName(String name) {
  57. this.name = name;
  58. }
  59. public int getAge() {
  60. return age;
  61. }
  62. public void setAge(int age) {
  63. this.age = age;
  64. }
  65. public String getSex() {
  66. return sex;
  67. }
  68. public void setSex(String sex) {
  69. this.sex = sex;
  70. }
  71. // 重写Object的tostring方法
  72. @Override
  73. public String toString() {
  74. return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]";
  75. }
  76. // Object的hashCode方法
  77. @Override
  78. public int hashCode() {
  79. final int prime = 31;
  80. int result = 1;
  81. result = prime * result + age;
  82. result = prime * result + ((name == null) ? 0 : name.hashCode());
  83. result = prime * result + ((sex == null) ? 0 : sex.hashCode());
  84. return result;
  85. }
  86. // 重写Objet的equasl方法
  87. @Override
  88. public boolean equals(Object obj) {
  89. if (this == obj)
  90. return true;
  91. if (obj == null)
  92. return false;
  93. if (getClass() != obj.getClass())
  94. return false;
  95. Person other = (Person) obj;
  96. if (age != other.age)
  97. return false;
  98. if (name == null) {
  99. if (other.name != null)
  100. return false;
  101. } else if (!name.equals(other.name))
  102. return false;
  103. if (sex == null) {
  104. if (other.sex != null)
  105. return false;
  106. } else if (!sex.equals(other.sex))
  107. return false;
  108. return true;
  109. }
  110. }
  111. 结果为:
  112. Person [name=WangWu, age=28, sex=male]
  113. Person [name=LiSi, age=32, sex=female]
  114. Person [name=ZhaoLiu, age=23, sex=female]
  115. Person [name=ZhangSan, age=23, sex=male]

总结:hasHSet,底层是哈希表的数据结构,使用了HasCode和equals方法保证了元素的唯一性。

LinkedHashSet特征:
1.LinkedHashSet是HashSet的子类,底层也是使用了哈希表的数据结构。
2.它的数据是有序的,只不过它迭代的顺序是添加的顺序,因为它底层用链表来记录添加元素的顺序。迭代时,再使用添加时顺序迭代。
LinkedHashSet实例:

  1. public class ComparableDemo {
  2. /**
  3. * @param args
  4. */
  5. public static void main(String[] args) {
  6. // 创建一个Set集合的引用指向LinkedHashSet的对象
  7. Set se = new LinkedHashSet();
  8. // 实例化1
  9. Person p1 = new Person("ZhangSan", 23, "male");
  10. // 实例化2
  11. Person p2 = new Person("LiSi", 32, "female");
  12. // 实例化3
  13. Person p3 = new Person("WangWu", 28, "male");
  14. // 实例化4
  15. Person p4 = new Person("ZhaoLiu", 23, "female");
  16. // 实例化5
  17. Person p5 = new Person("ZhangSan", 23, "male");
  18. // 将实例化对象添加进集合中
  19. se.add(p1);
  20. se.add(p2);
  21. se.add(p3);
  22. se.add(p4);
  23. se.add(p5);
  24. // 迭代集合中的元素
  25. Iterator<Person> it = se.iterator();
  26. // 判断集合中是否存在元素
  27. while (it.hasNext()) {
  28. // 迭代下一个元素
  29. Person per = it.next();
  30. // 打印元素
  31. System.out.println(per);
  32. }
  33. }
  34. }
  35. 结果为:
  36. Person [name=ZhangSan, age=23, sex=male]
  37. Person [name=LiSi, age=32, sex=female]
  38. Person [name=WangWu, age=28, sex=male]
  39. Person [name=ZhaoLiu, age=23, sex=female]

总结:LinkedHashSet集合是有序的,它结果的顺序是你添加元素的顺序,因为它底层用链表记录了添加元素的顺序。

TreeSet特征:
1.它的元素是有序的,无重复元素。它的线程是不安全的
2.它底层使用了二叉树的数据结构。
3.二叉树的原理:
1.它添加的第一个元素时根节点。
2.再添加第二个元素时,与根节点进行比较,如果比根节点大,那么就放在根节点的右侧的子节点位置,如果比根节点小,那么就放在根节点的左侧子节点的位置,如果相等,那么就添加失败。
3.添加第三个元素时,先与根节点进行比较,如果比根小,再与根的左侧比较,比它小放在它的左侧子节点,比它大放在它的右侧子节点。相等的话,添加失败。
如果比根答,再与根的右侧比较,比它大放在它的右侧子节点,比它小放在它的左侧子节点。相等的话,添加失败。
4.遍历二叉树的原则:先遍历左,然后当前,最后是右。
5.TreeSet有序的原则:(1)TreeSet有比较器,那么使用比较器来比较元素 (2)TreeSet没有比较器,实现Comparable接口,让它具有自然顺序。

TreeSet实例:

  1. import java.util.Comparator;
  2. import java.util.Iterator;
  3. import java.util.Set;
  4. import java.util.TreeSet;
  5. public class ComparableDemo {
  6. /**
  7. * @param args
  8. */
  9. public static void main(String[] args) {
  10. Comparator<Person> my = new Mycompare();
  11. // 创建一个Set集合的引用
  12. Set<Person> se = new TreeSet<Person>(my);
  13. // 实例化1
  14. Person p1 = new Person("ZhangSan", 23, "male");
  15. // 实例化2
  16. Person p2 = new Person("LiSi", 32, "female");
  17. // 实例化3
  18. Person p3 = new Person("WangWu", 28, "male");
  19. // 实例化4
  20. Person p4 = new Person("ZhaoLiu", 23, "female");
  21. // 实例化5
  22. Person p5 = new Person("ZhangSan", 23, "male");
  23. // 将实例化对象添加进集合中
  24. se.add(p1);
  25. se.add(p2);
  26. se.add(p3);
  27. se.add(p4);
  28. se.add(p5);
  29. // 迭代集合中的元素
  30. Iterator<Person> it = se.iterator();
  31. // 判断集合中是否存在元素
  32. while (it.hasNext()) {
  33. // 迭代下一个元素
  34. Person per = it.next();
  35. // 打印元素
  36. System.out.println(per);
  37. }
  38. }
  39. }
  40. class Mycompare implements Comparator<Person> {
  41. @Override
  42. public int compare(Person o1, Person o2) {
  43. // 从年龄开始比较
  44. int age = o1.getAge() - o2.getAge();
  45. if (age != 0) {
  46. return age;
  47. }
  48. // 如果年龄相等,从性别比较
  49. String o1sex = o1.getSex();
  50. String o2sex = o2.getSex();
  51. // 如果o1性别为男
  52. if (o1sex.equals("male")) {
  53. // 和如果o2性别为女,返回1,男大
  54. if (o2sex.equals("female")) {
  55. return -1;
  56. }
  57. } else {
  58. // 否则o2的性别为男时,o2比o1大
  59. if (o2sex.equals("male")) {
  60. return 1;
  61. }
  62. }
  63. return o1.getName().compareTo(o2.getName());
  64. }
  65. }
  66. 结果:
  67. Person [name=ZhangSan, age=23, sex=male]
  68. Person [name=ZhaoLiu, age=23, sex=female]
  69. Person [name=WangWu, age=28, sex=male]
  70. Person [name=LiSi, age=32, sex=female]

总结:在进行比较时,如果判断元素不唯一,比如,同姓名,同年龄,才视为同一个人。在判断时,需要分主要条件和次要条件,当主要条件相同时,再判断次要条件,按照次要条件排序。

二、Map集合
1、什么是Map集合?
Map是双列集合,它是以Entry属性的键值对(Key.Value)的对象存在的。
2、Map有什么特性?
1.它是双列集合,Key键不能重复,Value值可以重复。
3、Map有五种实现类。
他们分别是:HashMap、TreeMap、HashTable、properties、LinkedHashMap、
HashMap特征:
1.它的底层是用哈希表的数据结构
2.因为它的底层使用的是哈希表,所以它必须重写HashCode和equals方法。
3.线程不同步的。可以存储null键,null值
HashMap实例:

  1. import java.util.HashMap;
  2. import java.util.Map;
  3. import java.util.Map.Entry;
  4. import java.util.Set;
  5. public class MapDemo {
  6. /*
  7. * 统计候选人票数是一个道理 所有投票人把自己心中的人选提交上来。
  8. *
  9. * 张三把所有选票上的名字读一次,即循环遍历所有选票,并获取名字。 李四听到张三念一个,就在纸上找这个名字是否已经存在,如果存在,那么把票数+1
  10. * 如果不存在,那么把这个名字写上,在票数上写1。
  11. */
  12. public static void main(String[] args) {
  13. // 创建后候选人
  14. String s1 = "ZhanSan LiSi LiSi ZhanSan WangWu LiSi LiSi ZhanSan 张国荣";
  15. // 将返回的map创建成一个新的map集合
  16. Map<String, Integer> mp = fun(s1);
  17. // 将map集合转换为Set集合
  18. Set<Map.Entry<String, Integer>> entryset = mp.entrySet();
  19. // 遍历map集合
  20. for (Entry<String, Integer> s2 : entryset) {
  21. // 获取键
  22. String key = s2.getKey();
  23. // 获取值
  24. Integer vlaue = s2.getValue();
  25. // 将键和值打印
  26. System.out.println(key + "::" + vlaue);
  27. }
  28. }
  29. public static Map fun(String s1) {
  30. // 创建一个Map集合Map<String(候选人名字), Integer(票数)>
  31. Map<String, Integer> mp = new HashMap<String, Integer>();
  32. // 把参数字符串分隔成字符串数组;String[] names=s.split(" ");
  33. String[] names = s1.split(" ");
  34. // 循环遍历这个names
  35. for (int i = 0; i < names.length; i++) {
  36. int tokce = 1;
  37. // 判断mp中是否包含这个名字
  38. if (mp.containsKey(names[i])) {
  39. // 如果存在,获取票数(获取值),给值+1
  40. tokce = mp.get(names[i]) + 1;
  41. }
  42. mp.put(names[i], tokce);
  43. }
  44. return mp;
  45. }
  46. }
  47. 结果为:
  48. WangWu::1
  49. 张国荣::1
  50. ZhanSan::3
  51. LiSi::4

总结:Map自身没有遍历的方法,必须将其转换为Set集合然后遍历,转换的方法有两种:keySet();entrySet()

TreeMap特征:
1.它的底层是用二叉树结构
2.有序!使用键类型的自然顺序,或者TreeMap的比较器排序;
多重Map集合实例:

  1. import java.util.LinkedHashMap;
  2. import java.util.Map;
  3. import java.util.Set;
  4. public class MapDemo2 {
  5. /**
  6. * @param args
  7. */
  8. public static void main(String[] args) {
  9. // 创建一个大map中泛型左边类型的小map
  10. Map<String, String> gmsz = new LinkedHashMap<String, String>();
  11. // 创建大map中泛型的右边类型的小map
  12. Map<String, String> hjfw = new LinkedHashMap<String, String>();
  13. // 创建大map
  14. Map<String, Map<String, String>> mj = new LinkedHashMap<String, Map<String, String>>();
  15. // 向左边类型map添加元素
  16. gmsz.put("光明左使", "杨逍");
  17. gmsz.put("光明右使", "范遥");
  18. // 往右边类型map添加元素
  19. hjfw.put("紫衫龙王", "黛绮丝");
  20. hjfw.put("白眉鹰王", "殷天正");
  21. hjfw.put("金毛狮王", "谢逊");
  22. hjfw.put("青翼蝠王", "韦一笑");
  23. mj.put("光明使者", gmsz);
  24. mj.put("护教法王", hjfw);
  25. // 将大的map转换成set集合
  26. Set<String> keyset = mj.keySet();
  27. /*
  28. * Iterator<String> it = keyset.iterator();
  29. *
  30. * while (it.hasNext()) { String s1 = it.next(); Map<String, String> key
  31. * = mj.get(s1); System.out.println(key); }
  32. */
  33. // 使用高级for迭代set集合
  34. for (String st : keyset) {
  35. // 通过map的get方法获取键,返回右边小map的集合类型
  36. Map<String, String> st2 = mj.get(st);
  37. //将其打印
  38. System.out.println(st2);
  39. }
  40. }
  41. }
  42. 结果:
  43. {光明左使=杨逍, 光明右使=范遥}
  44. {紫衫龙王=黛绮丝, 白眉鹰王=殷天正, 金毛狮王=谢逊, 青翼蝠王=韦一笑}

总结:Map集合主要是以键值对的形式存在,Entry就是键值对对象,Map结果都是以{}表示的,和list、set的不同。遍历Set的两种方法。KeySet和entrySet。KeySet中遍历的返回的是Value值的类型,entrySet中遍历返回的是Entry对象的返回值类型

-————— android培训、java培训、java学习型技术博客、期待与您交流! ——————

发表评论

表情:
评论列表 (有 0 条评论,540人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Map集合

    【前言】 1.Map 用于保存具有映射关系的数据,因此Map集合里保存着两组值,一组值用于保存Map里key,另外一组值用于保存Map里的value,key和value都可以