Python+Selenium基础篇之6-元素定位方法(selenium如何定位元素)
406
2022-07-28
目录1. 数据模型介绍2. 简单使用介绍2.1 容器创建2.2 添加元素2.3 移除元素2.4 替换元素2.5 获取元素及遍历2.6 输出所有的key2.7 输出所有的value3. 小结
今天给大家介绍一个相对基础的知识点 HashMultmap;
guava基本上可以说是java开发项目中,大概率会引入的包,今天介绍的主角是一个特殊的容器 -- HashMultmap,可以简单的将它的数据结构理解为Map
那么为什么会突然想到介绍一下它呢,因为昨天刚因为对它理解不够深刻,把它当作了Map
1. 数据模型介绍
正常来讲,在使用一个新的数据对象时,我们应该先的了解它的数据模型;
直接看源码,会发现实际存储数据的结构为 Map
abstract class AbstractMapBasedMultimap
private transient Map
}
再jdk中Map也有很多实现,那么具体是哪个呢?
从构造方法出发,来看下这个map成员的初始化过程
private HashMultimap(int expectedKeys, int expectedValuesPerKey) {
super(Platform.newHashMapWithExpectedSize(expectedKeys));
this.expectedValuesPerKey = 2;
Preconditions.checkArgument(expectedValuesPerKey >= 0);
this.expectedValuesPerKey = expectedValuesPerKey;
}
private HashMultimap(Multimap extendsWBHSyaH K, ? extends V> multimap) {
super(Platform.newHashMapWithExpectedSize(multimap.keySet().size()));
this.expectedValuesPerKey = 2;
this.putAll(multimap);
}
关键点就在 Platform.newHashMapWithExpectedSize,熟悉的小伙伴已经能很快给出答案了,这个map就是我们常用的HashMap
接下来需要关注的就是value中的Collection,是什么容器类型了;对于它,则从添加元素的时候来定位put(key, value)
关键源码如下
public boolean put(@Nullable K key, @Nullable V value) {
Collection
if (collection == null) {
collection = this.createCollection(key);
if (collection.add(value)) {
++this.totalSize;
this.map.put(key, collection);
return true;
} else {
throw new AssertionError("New Collection violated the Collection spec");
}
} else if (collection.add(value)) {
++this.totalSize;
return true;
} else {
return false;
}
}
这个写法相信大家都不会陌生,存在时,直接添加到容器;不存在时,则通过 createCollection来创建容器,并塞入Map;其具体的实现逻辑如下
// com.google.common.collect.HashMultimap#createCollection
Set return Platform.newHashSetWithExpectedSize(this.expectedValuesPerKey); } 所以HashMultimap的底层数据存储就是我们的老朋友 HashMap 2. 简单使用介绍 基本来讲,HashMultimap的使用姿势非常简单了,下面给出简单实例演示一下,基本上看看就会了 2.1 容器创建 // 创建一个默认的 HashMap HashMultimap // 当我们知道容器的个数时,推荐使用下面这种方式, // HashMap 设置容量为8, 每个HashSet的容量初始化为16 HashMultimap // 另外一个就是基于MultMap来创建的case了 HashMultimap 注意上面的第三种实现,需要理解的是 map3.get(key) != map.get(key) 即基于原来的容器初始化的新容器,其value是一个新的容器对象,将之前的value中所有元素,都塞入新的容器中,并不是直接引用就的容器对象(这么一说是不是更想是深拷贝,而不是浅拷贝呢?) 2.2 添加元素 // 添加单个元素 map.put("hello", 510); // 添加多个元素 map.putAll("skill", Arrays.asList(1, 2, 3, 4, 1)); 注意 因为value是HashSet,所以重复的元素会忽略塞入重复的元素会忽略再次申明,添加重复的元素会忽略 (没错,我就是这里出了问题......) 2.3 移除元素 // 移除skill对应的集合中,value=3的元素 map.remove("skill", 3); // 移除key map.removeAll("hello"); 2.4 替换元素 如果我们希望将整个value都换成一个新的集合,那么可以使用replaceValue // 直接替换skill对应的value集合,新的值为 {100, 200, 300} map.replaceValues("skill", Arrays.asList(100, 200, 300)); 2.5 获取元素及遍历 // 获取对应的value集合,当不存在时,返回空集合(不是null,简直是贴心) Set foreach方式的迭代 for (Map.Entry System.out.println(entry.getKey() + ":" + entry.getValue()); } 注意上面的迭代成员 Map.Entry skill:200skill:100skill:300 2.6 输出所有的key // 输出所有的key, map.keys() // 输出key集合 map.keySet(); 他们两有啥区别?看个实例 HashMultimap map.replaceValues("skill", Arrays.asList(100, 200, 300)); System.out.println("keys=" + map.keys()); System.out.println("keySet=" + map.keySet()); 输出如下 keys=[skill x 3]keySet=[skill] 上面这个skill x 3是什么鬼,实际上表示skill有三个,返回的容器可以理解为List,不去重 而下面的KeySet()则返回的是个Set,会去重 2.7 输出所有的value map.values() 通过上面的再理解这个就简单了,所有的value都合并再一个List,接下来我们看一下两种遍历方式 HashMultimap map.putAll("skill", Arrays.asList(100, 200, 300)); map.put("a", 100); for (Integer v: map.values()) { System.out.println(v); } 实际输出如下 100100200300 3. 小结 这里主要介绍的是Gauva的容器HashMultimap的数据模型及使用姿势,知识点相对来说比较基础,再实际使用的时候,请牢记,把它看作是简单方便易使用的 HashMap 那么当我们希望value是个List时,可以怎么整呢? 此时可以使用 LinkedMultiValueMap 来替代,它的底层数据结构实际就是 HashMap 最后提一句,guava的这几个容器的实现,其源码阅读起来不会吃力,且设计思路也非常典型,比如如果让我们自己来基于jdk的基础容器实现一个类似的容器,如何优雅的去实现呢? 这里就给了一个标准答案,强烈推荐有兴趣的小伙伴瞅一下
return Platform.newHashSetWithExpectedSize(this.expectedValuesPerKey);
}
所以HashMultimap的底层数据存储就是我们的老朋友 HashMap
2. 简单使用介绍
基本来讲,HashMultimap的使用姿势非常简单了,下面给出简单实例演示一下,基本上看看就会了
2.1 容器创建
// 创建一个默认的 HashMap
HashMultimap
// 当我们知道容器的个数时,推荐使用下面这种方式,
// HashMap 设置容量为8, 每个HashSet的容量初始化为16
HashMultimap
// 另外一个就是基于MultMap来创建的case了
HashMultimap
注意上面的第三种实现,需要理解的是 map3.get(key) != map.get(key)
即基于原来的容器初始化的新容器,其value是一个新的容器对象,将之前的value中所有元素,都塞入新的容器中,并不是直接引用就的容器对象(这么一说是不是更想是深拷贝,而不是浅拷贝呢?)
2.2 添加元素
// 添加单个元素
map.put("hello", 510);
// 添加多个元素
map.putAll("skill", Arrays.asList(1, 2, 3, 4, 1));
注意
因为value是HashSet,所以重复的元素会忽略塞入重复的元素会忽略再次申明,添加重复的元素会忽略
(没错,我就是这里出了问题......)
2.3 移除元素
// 移除skill对应的集合中,value=3的元素
map.remove("skill", 3);
// 移除key
map.removeAll("hello");
2.4 替换元素
如果我们希望将整个value都换成一个新的集合,那么可以使用replaceValue
// 直接替换skill对应的value集合,新的值为 {100, 200, 300}
map.replaceValues("skill", Arrays.asList(100, 200, 300));
2.5 获取元素及遍历
// 获取对应的value集合,当不存在时,返回空集合(不是null,简直是贴心)
Set
foreach方式的迭代
for (Map.Entry
System.out.println(entry.getKey() + ":" + entry.getValue());
}
注意上面的迭代成员 Map.Entry
skill:200skill:100skill:300
2.6 输出所有的key
// 输出所有的key,
map.keys()
// 输出key集合
map.keySet();
他们两有啥区别?看个实例
HashMultimap
map.replaceValues("skill", Arrays.asList(100, 200, 300));
System.out.println("keys=" + map.keys());
System.out.println("keySet=" + map.keySet());
输出如下
keys=[skill x 3]keySet=[skill]
上面这个skill x 3是什么鬼,实际上表示skill有三个,返回的容器可以理解为List,不去重
而下面的KeySet()则返回的是个Set,会去重
2.7 输出所有的value
map.values()
通过上面的再理解这个就简单了,所有的value都合并再一个List,接下来我们看一下两种遍历方式
HashMultimap
map.putAll("skill", Arrays.asList(100, 200, 300));
map.put("a", 100);
for (Integer v: map.values()) {
System.out.println(v);
}
实际输出如下
100100200300
3. 小结
这里主要介绍的是Gauva的容器HashMultimap的数据模型及使用姿势,知识点相对来说比较基础,再实际使用的时候,请牢记,把它看作是简单方便易使用的 HashMap
那么当我们希望value是个List时,可以怎么整呢?
此时可以使用 LinkedMultiValueMap 来替代,它的底层数据结构实际就是 HashMap
最后提一句,guava的这几个容器的实现,其源码阅读起来不会吃力,且设计思路也非常典型,比如如果让我们自己来基于jdk的基础容器实现一个类似的容器,如何优雅的去实现呢? 这里就给了一个标准答案,强烈推荐有兴趣的小伙伴瞅一下
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~