c++ map 修改value_Set、Map实现类的简单介绍

597240ae76ea62fcbcf365c147cdc925.png

Collection是Java集合框架的的顶层接口,里面的子接口主要有Set和List两大类。

今天简单的总结一下,List接口下的实现类HashSet、TreeSet和LinkHashSet。

Map接口下的实现类有HashMap、LinkedHashMap、TreeMap

HashSet:

底层数据结构是为哈希表,他的工作原理如下图所示

24a17a01828f458fddccf456b1215fc8.png

它添加元素时离不开hashCode和equals方法,通过这两种方法进行去重和散列。上面的元素为Integer类型,Integer类型对象的hashCode就是数值的本身。存到HashSet的中的元素为无序元素。如果要把自定义对象写入HashSet里,就要对equals方法和hashCode方法进行重写。优点:添加、删除、查询效率高。缺点:无序。

LinkHashSet:

底层数据结构为哈希表+链表。

哈希表就如上图所示一样,用于散列元素并去重。链表用于维持添加顺序。如果要添加自定义对象也一样需要重写equals方法和hashCode方法。

TreeSet:

底层数据结构为二叉树。存储的数据按照一定的规则存储。存储规则让数据表现出自然顺序。我们随意存储1,2,3,30,10,4这几个数进去,画图理解可以得到下图的样式:

ba2ca6a2aa4a2c9a5dcafd8200960622.png

添加新元素的步骤:

[1] 如果集合无元素,t直接加入;如果集合有元素,t和根节点比较;

[2] 如果t小于根节点;把t放到根节点的左子树上;重复1-3步骤

[3] t大于根节点;把t放到根节点的右子树上;重复1-3步骤

输出时按照一定的规则:左子树->根节点->右子树

向TreeSet中添加元素时,一定要提供比较策略,否则会出现ClassCastException。即类型转换异常。当一个自定义对象作为元素要添加到TreeSet中,提供的比较策略可以用到内部比较器或者外部比较器。

内部比较器:自定义对象实现Comparable并实现compareTo方法时,通过指定具体的比较策略。比如说学生作为元素要添加到TreeSet中,Student类中实现Comparable接口:

public class Student implements Comparable<Student>{
 private String id;
 private String name;
 private int age;
 
 // 。。。
 
 @Override
 public String toString() {
  return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
 }
 
 @Override
 public int compareTo(Student o) {
  if(this.getAge()<o.getAge()) {
   return -1;
  }else if(this.getAge() == o.getAge()) {
   return 0;
  }else {
   return 1;
  }
 }
 
}

这里用学生的年龄作为比较策略。

比较策略一般当前对象写在前面,待比较对象也在后面,比较结果默认升序

return this.getAge() - o.getAge() ;

如果想要降序,改变两个比较对象的位置即可。

多种比较因素:

@Override
 public int compareTo(Student o) {
  /*if(this.getAge()<o.getAge()) {
   return -1;
  }else if(this.getAge() == o.getAge()) {
   return 0;
  }else {
   return 1;
  }*/
  
  // return  this.getAge() - o.getAge() ;
  
  if(this.getAge()<o.getAge()) {
   return -1;
  }else if(this.getAge() == o.getAge()) {
   return this.getName().compareTo(o.getName());
  }else {
   return 1;
  }
 }

像如果年龄相同,我们可以比较学生的姓名。

外部比较器:当实际开发过程中不知道添加元素的源代码、无权修改别人的代码,此时可以使用外部比较器。

Comparator 位于java.util包中,定义了compare(o1,o2) 用于提供外部比较策略。

TreeSet接受一个指定比较策略的构造方法,这些比较策略的实现类必须实现Comparator

接口。比如说我们用匿名内部类进行优化:

public class Test02 {
 public static void main(String[] args) {
  
  TreeSet<String> set2 = new TreeSet<String>(new Comparator<String>() {
 
   @Override
   public int compare(String o1, String o2) {
    return o1.length() - o2.length();
   }
   
  });
  
  set2.add("banana");
  set2.add("coco");
  set2.add("apple");
  
  set2.add("apple");
  System.out.println(set2);
  
 }
}

Map接口

Map接口称为键值对集合或者映射集合,其中的元素(entry)是以键值对(key-value)的形式存在。

Map 容器接口中提供了增、删、改、查的方式对集合进行操作。

Map接口中都是通过key来操作键值对,一般key是已知。通过key获取value。

map的接口的遍历

通过keySet() 返回map中键的set集合。下图是在API中查到的。

a64b281487b8266447c298a653a64718.png
public static void main(String[] args) {
 
  Map<String, String> map = new HashMap<String,String>();
  
  map.put("B", "banana");
  map.put("A", "apple");
  map.put("C", "coco");
  // map无序
  // 可以根据key的自然顺序 让map有序  => 一般用string作为key
  System.out.println(map);
  
  
  // 遍历
  Set<String> keys = map.keySet();
  for (String key : keys) {
   System.out.println(key+"=>"+map.get(key));
  }
  
  Iterator<String> it = keys.iterator();
  while(it.hasNext()) {
   String key = it.next();
   System.out.println(key+"=>"+map.get(key));
  }
 }

map中以键值对作为元素,键值对在map中称为entry,entrySet返回键值对的set集合。

20b7046a3518c3915031064c4b4c61c9.png
public static void main(String[] args) {
 
  Map<String, String> map = new HashMap<String,String>();
  
  map.put("B", "banana");
  map.put("A", "apple");
  map.put("C", "coco");
  // map无序
  // 可以根据key的自然顺序 让map有序  => 一般用string作为key
  System.out.println(map);
  
  // entrySet
  Set<Entry<String, String>> entrySet = map.entrySet();
  for (Entry<String, String> entry : entrySet) {
   System.out.println(entry.getKey()+"=>"+entry.getValue());
  }
  
  Iterator<Entry<String, String>> it2 = entrySet.iterator();
  while(it2.hasNext()) {
   Entry<String, String> entry = it2.next();
   System.out.println(entry.getKey()+"=>"+entry.getValue());
  }
 }

HashMap

HashMap 是Map的实现类,key以HashSet存储。

 public static void main(String[] args) {

  HashMap<Student, Object> map = new HashMap<Student,Object>();
  
  ArrayList<String> list1 = new ArrayList<String>();
  list1.add("alex");
  list1.add("alice");
  list1.add("allen");
  Student s1 = new Student("001", "大狗", 20);
  map.put(s1, list1);
  
  
  ArrayList<String> list2 = new ArrayList<String>();
  list2.add("ben");
  list2.add("bill");
  Student s2 = new Student("001", "大狗", 20);
  // 修改
  map.put(s2, list2);
  System.out.println(map);
  
 }

以上代码如果要实现修改的功能,要对Student的类进行hashcode方法和equals方法进行重写。

[1] 向HashMap中存储元素时,key一定要实现hashCode和equals

[2] 一般建议使用String作为Map接口的key。

LinkedHashMap

LinkedHashMap是Map接口的实现类,key以LinkedHashSet存储。

哈希表散列key,链表维持key的添加顺序。

 public static void main(String[] args) {

  HashMap<Student, Object> map = new HashMap<Student,Object>();
  
  ArrayList<String> list1 = new ArrayList<String>();
  list1.add("alex");
  list1.add("alice");
  list1.add("allen");
  Student s1 = new Student("001", "大狗", 20);
  map.put(s1, list1);
  
  
  ArrayList<String> list2 = new ArrayList<String>();
  list2.add("ben");
  list2.add("bill");
  Student s2 = new Student("001", "大狗", 20);
  // 修改
  map.put(s2, list2);
  System.out.println(map);
  
 }

以上代码如果要实现修改的功能,要对Student的类进行hashcode方法和equals方法进行重写。

TreeMap

TreeMap是Map的实现类,key以TreeSet存储。

public static void main(String[] args) {
  
  
  /*TreeMap<String, Object> map = new TreeMap<String,Object>(new Comparator<String>() {
 
   @Override
   public int compare(String o1, String o2) {
    return o1.length() - o2.length();
   }
  });
  
  ArrayList<String> list2 = new ArrayList<String>();
  list2.add("ben");
  list2.add("bill");
  map.put("Aa", list2);
  
  ArrayList<String> list1 = new ArrayList<String>();
  list1.add("alex");
  list1.add("alice");
  list1.add("allen");
  map.put("B", list1);
  
  System.out.println(map);*/
  
  
  
  TreeMap<Student, Object> map = new TreeMap<Student,Object>(new Comparator<Student>() {
 
   @Override
   public int compare(Student o1, Student o2) {
    return o1.getAge() - o2.getAge();
   }
  });
  
  ArrayList<String> list1 = new ArrayList<String>();
  list1.add("alex");
  list1.add("alice");
  list1.add("allen");
  Student s1 = new Student("001", "大狗", 20);
  map.put(s1, list1);
  
  
  ArrayList<String> list2 = new ArrayList<String>();
  list2.add("ben");
  list2.add("bill");
  Student s2 = new Student("001", "2狗", 20);
  // 修改
  map.put(s2, list2);
  System.out.println(map);
  
 }

这里用外部比较器Comparator匿名内部类,添加比较策略。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值