目录
Map是一种专门用来进行搜索的容器或者数据结构,其搜索的效率与其具体的实例化子类有关。对于静态类型的查找来说,一般直接遍历或者用二分查找【不会对区间进行插入和删除操作】
而在现实生活中的查找比如:
以上等可能在查找时进行一些插入和删除的操作,即动态查找,就需要用Map进行一系列操作。
注:Map最重要的特性就是去重!
当我们平常在做题时,遇到删除重复数据,或者找每个数据重复的此时等..都可以用Map来解决
Map是一个接口类,该类没有继承自Collection,该类中存储的是<K,V>结构的键值对,并且K一定是唯一的,不能重复。

<K,V>使用的是 key-value模型:
key-value 模型中 key 和 value 是一个整体,就类似于 我们一提起齐天大圣,就想起孙悟空。key-value模型就是类似于这样的一组组合。【key 和 value 互相修饰】
| 方法 | 解释 |
| V get(Object key) | 返回 key 对应的 value |
| V getOrDefault(Object key, V defaultValue) | 返回 key 对应的 value,key 不存在,返回默认值 |
| V put(K key, V value) | 设置 key 对应的 value |
| V remove(Object key) | 删除 key 对应的映射关系 |
| Set<K> keySet() | 返回所有 key 的不重复集合 |
| Collection<V> values() | 返回所有 value 的可重复集合 |
| Set<Map.Entry<K, V>> entrySet() | 返回所有的 key-value 映射关系 |
| boolean containsKey(Object key) | 判断是否包含 key |
| boolean containsValue(Object value) | 判断是否包含 value |
Map是接口类,不能实例化对象,所以只能实例化其实现类TreeMap或者HashMap
以下以TreeMap为例
1、put方法 设置 key 对应的 value【放置元素】
public static void main(String[] args) {
Map<String,Integer> map = new TreeMap<>();
map.put("abc",10);
map.put("hello",20);
map.put("hhf",23);
System.out.println(map);//Map类重写了toString方法
map.put("abc",20);//修改"abc"对应的value值
System.out.println(map);
}

2、get方法 返回 key 对应的值,key不存在则返回null
public static void main(String[] args) {
Map<String,Integer> map = new TreeMap<>();
map.put("abc",10);
System.out.println(map.get("abc"));//10
System.out.println(map.get("key"));//null
}
3、getOrDefault 方法 返回 key 对应的 value,key 不存在,返回默认值
public static void main(String[] args) {
Map<String,Integer> map = new TreeMap<>();
map.put("abc",10);
System.out.println(map.getOrDefault("abc", 19));//找到key值,则返回对应的value,输出10
System.out.println(map.getOrDefault("hello",20));//未找到key值,则返回默认值,输出20
}
4、remove 删除 key 对应的映射关系
public static void main(String[] args) {
Map<String,Integer> map = new TreeMap<>();
map.put("abc",10);
map.put("hello",20);
map.put("hhf",23);
System.out.println(map);
map.remove("abc");
System.out.println(map);
}

5、Set<K> keySet() 返回所有 key 的不重复集合,不包含value
public static void main(String[] args) {
Map<String,Integer> map = new TreeMap<>();
map.put("abc",10);
map.put("hello",20);
map.put("hhf",23);
map.put("world",20);
Set<String> set = map.keySet();
System.out.println(set);
}

'<V>'中V为 key的包装类型
set 中使用的模型是 key模型。
6、Collection<V> values() 返回所有 value 的可重复集合
public static void main(String[] args) {
Map<String,Integer> map = new TreeMap<>();
map.put("abc",10);
map.put("hello",20);
map.put("hhf",23);
map.put("world",20);
Collection<Integer> list = map.values();
System.out.println(list);
}

'<V>'中V为 value 的包装类型
7、Set<Map.Entry<K, V>> entrySet() 返回所有的 key-value 映射关系【重要】
entrySet方法能把TreeMap中的键值对打包,放入Set集合中。

public static void main(String[] args) {
Map<String,Integer> map = new TreeMap<>();
map.put("abc",10);
map.put("hello",20);
map.put("hhf",23);
Set<Map.Entry<String,Integer>> entrySet = map.entrySet();
}
上述代码中,map调用entrySet方法,把其内部的值全部打包为 Map.Entry<String,Integer> 类型,然后存储在 entrySet 变量中。

8、boolean containsKey(Object key) 判断是否包含 key
public static void main(String[] args) {
Map<String,Integer> map = new TreeMap<>();
map.put("abc",10);
map.put("hello",20);
map.put("hhf",23);
System.out.println(map.containsKey("hello"));// true
System.out.println(map.containsKey("world"));// fasle
}
9、boolean containsValue(Object value) 判断是否包含 value
public static void main(String[] args) {
Map<String,Integer> map = new TreeMap<>();
map.put("abc",10);
map.put("hello",20);
map.put("hhf",23);
System.out.println(map.containsValue(20));// true
System.out.println(map.containsValue(50));// false
}
Map.Entry<K, V> 是Map内部实现的用来存放<key, value>键值对映射关系的内部类
Entry是Map接口里面的接口
所以 TreeMap类实现Map接口时,也会具体实现Entry接口,HashMap内部也是如此
![]()
Map.Entry是为了更方便的输出Map键值对。一般情况下,要输出Map中的key 和 value 是先得到key的集合keySet(),然后再迭代(循环)由每个key得到每个value。values()方法是获取集合中的所有值,不包含键,没有对应关系。而Entry可以一次性获得这两个值。
| 方法 | 解释 |
| K getKey() | 返回 entry 中的 key |
| V getValue() | 返回 entry 中的 value |
| V setValue(V value) | 将键值对中的value替换为指定value/2、 |
这些方法都会结合着for循环进行操作,具体使用往下看
public static void main(String[] args) {
Map<String,Integer> map = new TreeMap<>();
map.put("abc",10);
map.put("hello",20);
map.put("hhf",23);
Set<Map.Entry<String,Integer>> entrySet = map.entrySet();
for(Map.Entry<String,Integer> entry : entrySet){
System.out.println("key: "+entry.getKey()+" value: "+entry.getValue());
}
}
TreeMap底层是一颗搜索树。而搜索树的插入是需要比较大小的,而TreeMap通过key来比较大小!所以key一定是编译器可以自动比较大小的。
public static void main(String[] args) {
Map<Integer,Integer> map1 = new TreeMap<>();
Map<String,Integer> map2 = new TreeMap<>();
map1.put(2,5);
map1.put(1,9);
map1.put(10,4);
map2.put("hello",2);
map2.put("world",20);
map2.put("weiwei",35);
System.out.println(map1);
System.out.println(map2);
}

当我们实现TreeMap类后,往里面传入自定义类就会报错!
所以,要想放入自定义类型,就要满足一下两个条件之一
1.自定义类型要实现Comparable ,重写compareTo
class People implements Comparable{ public int age; public int money; @Override public int compareTo(Object o) { return 0; } } public class Test3 { public static void main(String[] args) { Map<People,Integer> map = new TreeMap<>(); map.put(new People(),10); System.out.println(map); } }
2.实例化对象时传入一个比较器
class People implements{ public int age; public int money; } public class Test3 { public static void main(String[] args) { Map<People,Integer> map = new TreeMap<>(new Comparator<People>() { @Override public int compare(People o1, People o2) { return 0; } }); map.put(new People(),10); System.out.println(map); } }
以上两种方法,其实都是在告诉集合,自定义类型如何比较大小
同时不能放null,否则就会报错
如果两次put的key值一样,那么val值就会被替换掉
HashMap底层是一颗红黑树,存储的无序的,所以自定义类型和null都能直接存储,不会报错。
TreeMap 和 HashMap 底层实现逻辑不同,所以插入时间、删除时间、插入方法等都不相同
具体如下:
| Map底层结构 | TreeMap | HashMap |
| 底层结构 | 红黑树 | 哈希桶 |
| 插入/删除/查找时间 复杂度 | O(1) | |
| 是否有序 | 关于Key有序 | 无序 |
| 线程安全 | 不安全 | 不安全 |
| 插入/删除/查找区别 | 需要进行元素比较 | 通过哈希函数计算哈希地址 |
| 比较与覆写 | key必须能够比较,否则会抛出 ClassCastException异常 | 自定义类型需要覆写equals和 hashCode方法 |
| 应用场景 | 需要Key有序场景下 | Key是否有序不关心,需要更高的 时间性能 |
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po