首页 > 其他分享 >Guava中的增强Map - Table、BiMap、Multimap、RangeMap、ClassToInstanceMap

Guava中的增强Map - Table、BiMap、Multimap、RangeMap、ClassToInstanceMap

时间:2023-11-02 20:34:51浏览次数:43  
标签:Map Multimap ClassToInstanceMap System value put key println out

1. 简介

  日常开发中使用Map时经常会遇到很多复杂的处理场景,例如:多个键的Map、不仅可以根据键获取值也可以根据值获取键且不用遍历、重复键的Map、数字等范围内映射相同的值、内存中缓存对象等,Guava提供了以上场景的解决方案。

场景 解决方案 具体实现
多个键的Map Table HashBasedTable、TreeBasedTable、ImmutableTable
不仅可以根据键获取值也可以根据值获取键且不用遍历 BiMap HashBiMap、ImmutableBiMap
重复键的Map Multimap ArrayListMultimap、LinkedListMultimap、LinkedHashMultimap、ImmutableListMultimap、ImmutableSetMultimap
数字等范围内映射相同的值 RangeMap TreeRangeMap、ImmutableRangeMap
内存中缓存对象 ClassToInstanceMap MutableClassToInstanceMap、ImmutableClassToInstanceMap

  本博客将详细描述具体的示例代码。

2. 添加依赖

  Maven项目pom.xml中添加依赖:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>32.0.0-jre</version>
</dependency>

3. Tbale - 表结构数据

  官方注释翻译:将一对有序键(称为行键和列键)与单个值相关联的集合。
  示例代码(需求: 记录各个公司每个部门的人数):

// HashMap
Map<String, Integer> deptMap = new HashMap<>();
deptMap.put("A部门", 10);
deptMap.put("B部门", 20);
Map<String, Map<String, Integer>> companyMap = new HashMap<>();
companyMap.put("xx公司", deptMap);
// HashMap 获取值
Integer val = companyMap.get("xx公司").get("A部门");
System.out.println("HashMap 获取值: " + val);

// 创建Hash类型Table, 基于Hash表实现
// Table<R, C, V>中三个泛型: R-行, C-列, V-值
Table<String, String, Integer> hashTable = HashBasedTable.create();
hashTable.put("xx公司", "A部门", 10);
hashTable.put("xx公司", "B部门", 20);
hashTable.put("xx公司", "C部门", 30);

System.out.println("\nHash Table: " + hashTable);

// 创建Tree类型Table, 基于红黑树实现
Table<String, String, Integer> treeTable = TreeBasedTable.create();
treeTable.put("xx公司", "C部门", 30);
treeTable.put("xx公司", "B部门", 20);
treeTable.put("xx公司", "A部门", 10);

System.out.println("\nTree Table: " + treeTable);

// 创建不可变Table, 无法新增、更新或删除
Table<String, String, Integer> immutableTable = ImmutableTable.<String, String, Integer>builder()
        .put("xx公司", "C部门", 30)
        .put("xx公司", "B部门", 20)
        .put("xx公司", "A部门", 10)
        .build();

System.out.println("\nImmutable Table: " + immutableTable);

// Table 获取值
Integer val2 = hashTable.get("xx公司", "A部门");
System.out.println("\nTable 获取值: " + val2);

// Table 删除值
Integer remove = hashTable.remove("xx公司", "C部门");
System.out.println("\nTable 删除值: " + remove);

// 根据行获取列和值映射
Map<String, Integer> columnvalueMap = hashTable.row("xx公司");
System.out.println("\nTable 列和值 映射: " + columnvalueMap);

// 根据列获取行和值映射
Map<String, Integer> rowvalueMap = hashTable.column("A部门");
System.out.println("\nTable 行和值 映射: " + rowvalueMap);

// 获取key集合
Set<String> rowKeySet = hashTable.rowKeySet();
System.out.println("\nTable Row key 集合: " + rowKeySet);
Set<String> columnKeySet = hashTable.columnKeySet();
System.out.println("\nTable Column key 集合: " + columnKeySet);

// 获取值集合
Collection<Integer> values = hashTable.values();
System.out.println("\nTable 值集合: " + values);

// 判断包含行
boolean containsRow = hashTable.containsRow("xx公司");
System.out.println("\nTable 包含行: " + containsRow);

// 判断包含列
boolean containsColumn = hashTable.containsColumn("A部门");
System.out.println("\nTable 包含列: " + containsColumn);

// 判断包含行和列
boolean contains = hashTable.contains("xx公司", "A部门");
System.out.println("\nTable 包含行和列: " + contains);

// 判断包含值
boolean containsValue = hashTable.containsValue(10);
System.out.println("\nTable 包含值: " + containsValue);

// 行和列转置 - 行 转 列
Table<String, String, Integer> transposeTable = Tables.transpose(hashTable);

// 获取所有的行
Set<Table.Cell<String, String, Integer>> cells = transposeTable.cellSet();

// 遍历输出
System.out.println("\n遍历输出开始----------------------------");
cells.forEach(cell -> System.out.println(cell.getRowKey() + ", " + cell.getColumnKey() + ", " + cell.getValue()));
System.out.println("\n遍历输出结束----------------------------");

// 转换为嵌套的Map
Map<String, Map<String, Integer>> rowMap = hashTable.rowMap();
System.out.println("\nTable RowMap: " + rowMap);
Map<String, Map<String, Integer>> columnMap = hashTable.columnMap();
System.out.println("\nTable ColumnMap: " + columnMap);

  执行结果:

HashMap 获取值: 10

Hash Table: {xx公司={A部门=10, B部门=20, C部门=30}}

Tree Table: {xx公司={A部门=10, B部门=20, C部门=30}}

Immutable Table: {xx公司={C部门=30, B部门=20, A部门=10}}

Table 获取值: 10

Table 删除值: 30

Table 列和值 映射: {A部门=10, B部门=20}

Table 行和值 映射: {xx公司=10}

Table Row key 集合: [xx公司]

Table Column key 集合: [A部门, B部门]

Table 值集合: [10, 20]

Table 包含行: true

Table 包含列: true

Table 包含行和列: true

Table 包含值: true

遍历输出开始----------------------------
A部门, xx公司, 10
B部门, xx公司, 20

遍历输出结束----------------------------

Table RowMap: {xx公司={A部门=10, B部门=20}}

Table ColumnMap: {A部门={xx公司=10}, B部门={xx公司=20}}

4. BiMap - 双向映射Map

  官方注释翻译:双映射(或“双向映射”)是一种保留其值及其键的唯一性的映射。此约束使双映射能够支持“反向视图”,即另一个双映射,其中包含与此双映射相同的条目,但具有相反的键和值。
  示例代码(需求: 数组和英文翻译):

// 创建BiMap, 底层为两个Hash表的Map
BiMap<Integer, String> biMap = HashBiMap.create();
biMap.put(1, "one");
biMap.put(2, "two");
biMap.put(3, "three");
biMap.put(4, "four");
biMap.put(5, "five");

System.out.println("BiMap: " + biMap);

// 创建不可变BiMap, 无法新增、更新或删除
BiMap<Object, Object> immutableBiMap = ImmutableBiMap.builder()
        .put(1, "one")
        .put(2, "two")
        .put(3, "three")
        .put(4, "four")
        .put(5, "five")
        .build();

System.out.println("\nImmutable BiMap: " + immutableBiMap);

// 通过key获取value
String value = biMap.get(1);
System.out.println("\nBiMap 根据key获取value: " + value);

Integer key = biMap.inverse().get("one");
System.out.println("\nBiMap 根据value获取key: " + key);

// 翻转后修改
biMap.inverse().put("six", 6);
// 返回双映射的逆视图, 并没有创建新对象, 还是之前的对象, 所以操作翻转后的BiMap会影响之前的BiMap
System.out.println("\nBiMap 被影响: " + biMap);

// 底层是HashMap, key不可重复
// value不可重复
try {
    biMap.put(11, "one");
} catch (Exception e) {
    System.err.println("BiMap 替换value异常: " + e.getMessage());
}

// 翻转后key不能重复
try {
    biMap.inverse().put("first", 1);
} catch (Exception e) {
    System.err.println("BiMap 替换key异常: " + e.getMessage());
}

// key和value可为null
biMap.put(null, null);
System.out.println("\nBiMap 根据Null key获取Null value: " + biMap.get(null));
System.out.println("\nBiMap 根据Null value获取Null key: " + biMap.inverse().get(null));

// 强制替换key
biMap.forcePut(11, "one");
System.out.println("\nBiMap 获取新key: " + biMap.inverse().get("one"));

// values为Set集合
Set<String> values = biMap.values();
System.out.println("\nBiMap 不重复的value: " + values);

  执行结果:

BiMap: {1=one, 2=two, 3=three, 4=four, 5=five}

Immutable BiMap: {1=one, 2=two, 3=three, 4=four, 5=five}

BiMap 根据key获取value: one

BiMap 根据value获取key: 1

BiMap 被影响: {1=one, 2=two, 3=three, 4=four, 5=five, 6=six}
BiMap 替换value异常: value already present: one
BiMap 替换key异常: key already present: 1

BiMap 根据Null key获取Null value: null

BiMap 根据Null value获取Null key: null

BiMap 获取新key: 11

BiMap 不重复的value: [two, three, four, five, six, null, one]

5. Multimap - 多重映射Map

  官方注释翻译将键映射到值的集合,类似于 Map,但其中每个键可能与 多个 值相关联。
  示例代码(需求: 学生和各科选修课成绩):

// 创建Multimap, key为HashMap, value为ArrayList
Multimap<String, Integer> arrayListMultimap = ArrayListMultimap.create();
arrayListMultimap.put("张三", 90);
arrayListMultimap.put("张三", 80);
arrayListMultimap.put("张三", 100);
arrayListMultimap.put("李四", 88);

System.out.println("Multimap key为HashMap, value为ArrayList: " + arrayListMultimap);

// 创建Multimap, key为HashMap, value为HashSet
Multimap<String, Integer> hashMultimap = HashMultimap.create();
hashMultimap.put("张三", 90);
hashMultimap.put("张三", 80);
hashMultimap.put("张三", 100);
hashMultimap.put("李四", 88);

System.out.println("\nMultimap key为HashMap, value为HashSet: " + hashMultimap);

// 创建Multimap, key为LinkedHashMap, value为LinkedList
Multimap<String, Integer> linkedListMultimap = LinkedListMultimap.create();
linkedListMultimap.put("张三", 90);
linkedListMultimap.put("张三", 80);
linkedListMultimap.put("张三", 100);
linkedListMultimap.put("李四", 88);

System.out.println("\nMultimap key为LinkedHashMap, value为LinkedList: " + linkedListMultimap);

// 创建Multimap, key为LinkedHashMap, value为LinkedHashMap
Multimap<String, Integer> linkedHashMultimap = LinkedHashMultimap.create();
linkedHashMultimap.put("张三", 90);
linkedHashMultimap.put("张三", 80);
linkedHashMultimap.put("张三", 100);
linkedHashMultimap.put("李四", 88);

System.out.println("\nMultimap key为LinkedHashMap, value为LinkedHashMap: " + linkedHashMultimap);

// 创建Multimap, key为TreeMap, value为TreeSet
Multimap<String, Integer> treeMultimap = TreeMultimap.create();
treeMultimap.put("张三", 90);
treeMultimap.put("张三", 80);
treeMultimap.put("张三", 100);
treeMultimap.put("李四", 88);

System.out.println("\nMultimap key为TreeMap, value为TreeSet: " + treeMultimap);

// 创建不可变Multimap, 无法新增、更新或删除, key为ImmutableMap, value为ImmutableList
Multimap<String, Integer> immutableListMultimap = ImmutableListMultimap.<String, Integer>builder()
        .put("张三", 90)
        .put("张三", 80)
        .put("张三", 100)
        .put("李四", 88)
        .build();

System.out.println("\nMultimap key为ImmutableMap, value为ImmutableList: " + immutableListMultimap);

// 创建不可变Multimap, 无法新增、更新或删除, key为ImmutableMap, value为ImmutableSet
Multimap<String, Integer> immutableSetMultimap = ImmutableSetMultimap.<String, Integer>builder()
        .put("张三", 90)
        .put("张三", 80)
        .put("张三", 100)
        .put("李四", 88)
        .build();

System.out.println("\nMultimap key为ImmutableMap, value为ImmutableSet: " + immutableSetMultimap);

// 获取值
Collection<Integer> values = arrayListMultimap.get("张三");
System.out.println("\nMultimap 获取值集合: " + values);

// 获取不存在key的值, 返回的是空集合, 而不是null
Collection<Integer> valuesByNotExistsKey = arrayListMultimap.get("王五");
System.out.println("\nMultimap 获取不存在的Key值集合: " + valuesByNotExistsKey);

// 获取值集合添加值
// 返回的是多重映射中关联的值的视图集合, 并没有创建新对象, 还是之前的对象, 所以操作值集合会影响之前的Multimap
values.add(60);
System.out.println("\nMultimap 被影响: " + arrayListMultimap);

// 获取大小
System.out.println("\nMultimap 大小:" + arrayListMultimap.size());

// 判断是否为空
System.out.println("\nMultimap 是否为空: " + arrayListMultimap.isEmpty());

// 包含key
System.out.println("\nMultimap 包含key: " + arrayListMultimap.containsKey("张三"));

// 包含value
System.out.println("\nMultimap 包含value: " + arrayListMultimap.containsValue(60));

// 包含key-value键值对
System.out.println("\nMultimap 包含key-value对: " + arrayListMultimap.containsEntry("张三", 60));

// 替换value
arrayListMultimap.replaceValues("张三", Arrays.asList(10, 20, 30));
System.out.println("\nMultimap 替换value: " + arrayListMultimap);

// 根据key-value删除
arrayListMultimap.remove("张三", 10);
System.out.println("\nMultimap 根据key-value删除: " + arrayListMultimap);

// 根据key删除
Collection<Integer> removeAll = arrayListMultimap.removeAll("张三");
System.out.println("\nMultimap 根据key删除: " + removeAll);

// 获取key集合
Set<String> keySet = arrayListMultimap.keySet();
System.out.println("\nMultimap 获取key集合(HashSet): " + keySet);
Multiset<String> keys = arrayListMultimap.keys();
System.out.println("\nMultimap 获取key集合(MultiSet): " + keys);

// 获取所有的key-value
Collection<Map.Entry<String, Integer>> entries = arrayListMultimap.entries();
System.out.println("\n遍历key-value开始--------------------------");
entries.forEach(entry -> System.out.println(entry.getKey() + " : " + entry.getValue()));
System.out.println("\n遍历key-value结束--------------------------");

// 转换为Map<K, Collection<V>>
Map<String, Collection<Integer>> collectionMap = arrayListMultimap.asMap();
System.out.println("\nMultimap 转换为Map<K, Collection<V>>: " + collectionMap);

  执行结果:

Multimap key为HashMap, value为ArrayList: {李四=[88], 张三=[90, 80, 100]}

Multimap key为HashMap, value为HashSet: {李四=[88], 张三=[80, 100, 90]}

Multimap key为LinkedHashMap, value为LinkedList: {张三=[90, 80, 100], 李四=[88]}

Multimap key为LinkedHashMap, value为LinkedHashMap: {张三=[90, 80, 100], 李四=[88]}

Multimap key为TreeMap, value为TreeSet: {张三=[80, 90, 100], 李四=[88]}

Multimap key为ImmutableMap, value为ImmutableList: {张三=[90, 80, 100], 李四=[88]}

Multimap key为ImmutableMap, value为ImmutableSet: {张三=[90, 80, 100], 李四=[88]}

Multimap 获取值集合: [90, 80, 100]

Multimap 获取不存在的Key值集合: []

Multimap 被影响: {李四=[88], 张三=[90, 80, 100, 60]}

Multimap 大小:5

Multimap 是否为空: false

Multimap 包含key: true

Multimap 包含value: true

Multimap 包含key-value对: true

Multimap 替换value: {李四=[88], 张三=[10, 20, 30]}

Multimap 根据key-value删除: {李四=[88], 张三=[20, 30]}

Multimap 根据key删除: [20, 30]

Multimap 获取key集合(HashSet): [李四]

Multimap 获取key集合(MultiSet): [李四]

遍历key-value开始--------------------------
李四 : 88

遍历key-value结束--------------------------

Multimap 转换为Map<K, Collection<V>>: {李四=[88]}

6. RangeMap - 范围映射Map

  官方注释翻译:从不相交的非空范围到非 null 值的映射。查询查找与包含指定键的范围(如果有)关联的值。
  示例代码(需求:考试成绩分类):

// if-else
int score = 88;
String rank;
if (0 <= score && score < 60) {
    rank = "不及格";
} else if (60 <= score && score <= 84) {
    rank = "及格";
} else if (84 < score && score <= 100) {
    rank = "优秀";
} else {
    rank = "无效";
}

System.out.println("if-else 获取值: " + rank);

// 创建RangeMap, 基于TreeMap(红黑树)实现
RangeMap<Integer, String> treeRangeMap = TreeRangeMap.create();
treeRangeMap.put(Range.closedOpen(0, 60), "不及格");
treeRangeMap.put(Range.closed(60, 84), "及格");
treeRangeMap.put(Range.openClosed(84, 100), "优秀");
treeRangeMap.put(Range.lessThan(0), "无效");
treeRangeMap.put(Range.greaterThan(100), "无效");

rank = treeRangeMap.get(score);
System.out.println("\nRangeMap 获取值: " + rank);

// 创建不可变RangeMap, 无法新增、更新或删除
ImmutableRangeMap<Integer, String> immutableRangeMap = ImmutableRangeMap.<Integer, String>builder()
        .put(Range.closedOpen(0, 60), "不及格")
        .put(Range.closed(60, 84), "及格")
        .put(Range.openClosed(84, 100), "优秀")
        .put(Range.lessThan(0), "无效")
        .put(Range.greaterThan(100), "无效")
        .build();

rank = immutableRangeMap.get(score);
System.out.println("\nImmutableRangeMap 获取值: " + rank);

// 获取key-value对
Map.Entry<Range<Integer>, String> entry = treeRangeMap.getEntry(88);
System.out.println("\nRangeMap 获取key-value对: " + entry.getKey() + " : " + entry.getValue());

// 返回不可变的升序的Map
Map<Range<Integer>, String> asMapOfRanges = treeRangeMap.asMapOfRanges();
System.out.println("\nRangeMap 不可变的升序的Map: " + asMapOfRanges);

// 返回不可变的降序的Map
Map<Range<Integer>, String> asDescendingMapOfRanges = treeRangeMap.asDescendingMapOfRanges();
System.out.println("\nRangeMap 不可变的降序的Map: " + asDescendingMapOfRanges);

// 相连范围合并
RangeMap<Integer, String> treeRangeMap2 = TreeRangeMap.create();
treeRangeMap2.putCoalescing(Range.closedOpen(0, 60), "不及格");
treeRangeMap2.putCoalescing(Range.closed(60, 84), "及格");
treeRangeMap2.putCoalescing(Range.openClosed(84, 100), "及格"); // 或者 [60..84]范围合并
treeRangeMap2.putCoalescing(Range.lessThan(0), "无效");
treeRangeMap2.putCoalescing(Range.greaterThan(100), "无效");
System.out.println("\nRangeMap 不合并相连范围: " + treeRangeMap.asMapOfRanges());
System.out.println("RangeMap 合并相连范围: " + treeRangeMap2.asMapOfRanges());

// 最小范围
Range<Integer> span = treeRangeMap.span();
System.out.println("\nRangeMap 最小范围: " + span);

// 子范围Map
RangeMap<Integer, String> subRangeMap = treeRangeMap.subRangeMap(Range.closed(70, 90));
System.out.println("\nRangeMap 子范围Map: " + subRangeMap);

// 合并范围
treeRangeMap.merge(Range.closed(60, 100), "及格", (s, s2) -> s2);
System.out.println("\nRangeMap 合并Map: " + treeRangeMap);

// 移除范围
treeRangeMap.remove(Range.open(90, 95));
System.out.println("\nRangeMap 移除范围: " + treeRangeMap);

// 清除所有范围
treeRangeMap.clear();
System.out.println("\nRangeMap 清除所有范围: " + treeRangeMap);

  执行结果:

if-else 获取值: 优秀

RangeMap 获取值: 优秀

ImmutableRangeMap 获取值: 优秀

RangeMap 获取key-value对: (84..100] : 优秀

RangeMap 不可变的升序的Map: {(-∞..0)=无效, [0..60)=不及格, [60..84]=及格, (84..100]=优秀, (100..+∞)=无效}

RangeMap 不可变的降序的Map: {(100..+∞)=无效, (84..100]=优秀, [60..84]=及格, [0..60)=不及格, (-∞..0)=无效}

RangeMap 不合并相连范围: {(-∞..0)=无效, [0..60)=不及格, [60..84]=及格, (84..100]=优秀, (100..+∞)=无效}
RangeMap 合并相连范围: {(-∞..0)=无效, [0..60)=不及格, [60..100]=及格, (100..+∞)=无效}

RangeMap 最小范围: (-∞..+∞)

RangeMap 子范围Map: {[70..84]=及格, (84..90]=优秀}

RangeMap 合并Map: [(-∞..0)=无效, [0..60)=不及格, [60..84]=及格, (84..100]=及格, (100..+∞)=无效]

RangeMap 移除范围: [(-∞..0)=无效, [0..60)=不及格, [60..84]=及格, (84..90]=及格, [95..100]=及格, (100..+∞)=无效]

RangeMap 清除所有范围: []

7. ClassToInstanceMap - 类型映射到实例Map

  官方注释翻译:映射,其每个条目将一个 Java 原始类型 映射到该类型的实例。除了实现 Map之外,还提供额外的类型安全操作 putInstance 和 getInstance 。与任何其他 Map<Class, Object>映射一样,此映射可能包含基元类型的条目,并且基元类型及其相应的包装器类型可以映射到不同的值。
  示例代码(需求:缓存Bean(不交给Spring管理,自己管理Bean)):

class UserBean {
    private final Integer id;
    private final String username;

    public UserBean(Integer id, String username) {
        this.id = id;
        this.username = username;
    }

    @Override
    public String toString() {
        return "UserBean{" + "id=" + id + ", username='" + username + '\'' + '}';
    }
}
// 创建Bean
UserBean userBean = new UserBean(1, "张三");

// HashMap
HashMap<Class, Object> hashMap = new HashMap<>();
hashMap.put(UserBean.class, userBean);

// 获取值,需要强转
UserBean value = (UserBean) hashMap.get(UserBean.class);
System.out.println("HashMap 获取对象实例: " + value);
System.out.println("HashMap 获取对象实例等于创建的Bean: " + (value == userBean));

// 创建ClassToInstanceMap
ClassToInstanceMap<Object> classToInstanceMap = MutableClassToInstanceMap.create();
classToInstanceMap.putInstance(UserBean.class, userBean);

// 获取值,无需强转
UserBean value2 = classToInstanceMap.getInstance(UserBean.class);
System.out.println("\nClassToInstanceMap 获取对象实例: " + value2);
System.out.println("ClassToInstanceMap 获取对象实例等于创建的Bean: " + (value2 == userBean));

// 创建不可变ClassToInstanceMap, 无法新增、更新或删除
ClassToInstanceMap<UserBean> immutableClassToInstanceMap = ImmutableClassToInstanceMap.<UserBean>builder()
        .put(UserBean.class, userBean)
        .build();

// 获取值,无需强转
UserBean value3 = immutableClassToInstanceMap.getInstance(UserBean.class);
System.out.println("\nImmutableClassToInstanceMap 获取对象实例: " + value3);
System.out.println("ImmutableClassToInstanceMap 获取对象实例等于创建的Bean: " + (value3 == userBean));


// 限制类型,避免使用HashMap存储对象时,因为使用Object值类型而在添加缓存时需要今天类型校验
ClassToInstanceMap<Collection> classToInstanceMap1 = MutableClassToInstanceMap.create();
classToInstanceMap1.put(ArrayList.class, new ArrayList());
classToInstanceMap1.put(HashSet.class, new HashSet());
// 编译保存: 'put(java.lang.Class<? extends [email protected] Collection>, java.util.Collection)' in 'com.google.common.collect.MutableClassToInstanceMap' cannot be applied to '(java.lang.Class<java.util.HashMap>, java.util.HashMap)'
//        classToInstanceMap1.put(HashMap.class, new HashMap());

  执行结果:

HashMap 获取对象实例: UserBean{id=1, username='张三'}
HashMap 获取对象实例等于创建的Bean: true

ClassToInstanceMap 获取对象实例: UserBean{id=1, username='张三'}
ClassToInstanceMap 获取对象实例等于创建的Bean: true

ImmutableClassToInstanceMap 获取对象实例: UserBean{id=1, username='张三'}
ImmutableClassToInstanceMap 获取对象实例等于创建的Bean: true

标签:Map,Multimap,ClassToInstanceMap,System,value,put,key,println,out
From: https://www.cnblogs.com/cao-lei/p/17806222.html

相关文章

  • map知识点总结
    map是STL的一个关联容器,它提供一对一的hash(哈希表)第一个可以称为关键字(key),每个关键字只能在map中出现一次;第二个可能称为该关键字的值(value);map以模板(泛型)方式实现,可以存储任意类型的数据,包括使用者自定义的数据类型。Map主要用于资料一对一映射(one-to-one)的情況,map內部......
  • HashMap的长度是2的幂次方
    为了能让HashMap存取高效,尽量减少碰撞,也就是要尽量把数据分配均匀。Hash值的范围值-2147483648到2147483647,前后加起来大概40亿的映射长度,只要哈希函数映射的比较均匀松散,一般应用是很难出现碰撞的。但问题是一个40亿长度的数组,内存是放不下的。所以这个散列值是不能直接拿来用的。......
  • tsne、umap可视化简单例子
    importnumpyasnpfromsklearn.manifoldimportTSNEfromsklearn.decompositionimportPCAimportmatplotlib.pyplotaspltimportumapimporttorchX=torch.load('embeddings.pt')#(19783,16)y=np.load('labels.npy')#reduced_x=......
  • .NET6 配置 AutoMapper 与 AutoFac
    AutoMapper 概述1、什么是AutoMapper简单来说,AutoMapper就是一个用C#语言开发的一个轻量的处理一个实体对象到另外一个实体对象映射关系的组件库 官网地址:AutoMapper 文档地址:AutoMapper—AutoMapperdocumentation 2、为什么要用AutoMapper层与层之间的数据转换......
  • TreeMap
    TreeMap是Map家族中的一员,也是用来存放key-value键值对的。平时在工作中使用的可能并不多,它最大的特点是遍历时是有顺序的,根据key的排序规则来TreeMap是一个双列集合,是Map的子类。底层由红黑树结构构成。TreeMap是一个基于key有序的keyvalue散列表。map根据其键的自然顺序排......
  • minimap2安装使用
    官网:https://github.com/lh3/minimap2https://github.com/lh3/minimap2/releases/tag/v2.17 Downloadandinstall:wgethttps://github.com/lh3/minimap2/releases/download/v2.17/minimap2-2.17_x64-linux.tar.bz2tar-jxvfminimap2-2.17_x64-linux.tar.bz2cdminimap2-2.17......
  • javaweb--resultMap
    resultMap可以灵活的实现数据库列名和java类中的属性名的映射 1、定义<resultMap>标签2、在<select>标签中,使用resultMap属性替换resultType属性 ......
  • .NET6 使用AutoMapper
    .NET6使用AutoMapper 一、Net6环境下的.netcore项目里如何使用AutoMapper实现依赖注入。注:AutoMapper是一个对象-对象映射器,可以将一个对象映射到另一个对象。第一步,在Nuget引入AutoMapper、AutoMapper.Extensions.DependencyInjection这两个NuGet包  ......
  • 通过计算巢轻松部署 Ansible Semaphore
    概述AnsibleSemaphore是一个现代化的Ansible用户界面。可以轻松运行AnsiblePlaybook,获取有关失败的通知,并控制部署系统的访问权限。如果你的项目已经发展壮大,从终端进行部署不再适合你,那么AnsibleSemaphore就是所需要的东西。阿里云计算巢是一个给企业应用服务商和其客......
  • javaweb--Mapper代理开发
     1、使Mapper接口和SQL映射文件放置在同一文件夹下,可以在resources文件夹下新建一个和SQL映射文件相同的文件夹(例如:com/avb/Mapper)不能用.分割文件夹,用/ 2、把SQL映射表里的namespace属性为Mapper接口的全限定名 3、在Mapper中定义方法,方法名是SQL映射文件中sql语句的id,并......