Map和Set:用来进行搜索的集合类。
存储元素的类型:K-V模型(键值对)和K模型
K-V模型:统计一个文件中单词出现的次数。
K模型:在词典中找一个单词。
Map中存储的是K-V模型,Set中只存储了K。共同点:K不能重复。
Map
1.Map是一个接口,没有继承Collection类。
2.Map中存储的是K-V接口的键值对,并且要求K不能重复,但是V可以重复。
3.Map中的键值对体现:在Map内部定义Entry接口,该接口中包含有K,V
1.Map.Entry
Map.Entry<K, V> 即 Map 中定义的 K 类型的 key 和 V 类型的 value 的映射关系的类。
方法 | 解释 |
---|---|
K getKey() | 返回 entry 中的 key |
V getValue() | 返回 entry 中的 value |
V setValue(V value) | 将键值对中的value替换为指定value |
2.Map接口包含的常用方法:
- V put(K key, V value) 设置 key 对应的 value:
如果key不存在,将该key-value组成的键值对插入。
如果key存在,使用value替换原key所对应的value。
在插入key-value期间,Map会保证key是一个有序的序列—延伸期间肯定要对key进行比较----->延伸:如果key是自定义 类型的元素,该类的对象必须要能够比大小—>实现Comparable接口Comparator。
key是一定不能为空的,如果为空会抛NullPointerException—>原因:key为空无法进行比较,value可以为空。
public class MapTest2 {
public static void testTreeMap() {
Map<String,String> m1 = new TreeMap<>();
m1.put("peach","桃子");//插入键值对
m1.put("orange","橘子");
System.out.println(m1.put("apple","苹果"));
System.out.println(m1.size());
System.out.println(m1);
//验证key是否可以重复
//返回值:如果key不存在,将该键值对插入,返回null
// 如果key存在,用value覆盖原key的value
System.out.println(m1.put("orange","橙子"));
System.out.println(m1.size());
System.out.println(m1);
//key是一定不能为空的,如果为空会抛NullPointerException--->原因:key为空无法进行比较
//m1.put(null,"无名");
//value可以为空
m1.put("banana",null);
System.out.println(m1.size());
System.out.println(m1);
}
public static void main(String[] args){
testTreeMap();
}
}
/*
打印结果
null
3
{apple=苹果, orange=橘子, peach=桃子}
橘子
3
{apple=苹果, orange=橙子, peach=桃子}
4
{apple=苹果, banana=null, orange=橙子, peach=桃子}
*/
- V get(Object key) 返回 key 对应的 value:
如果key存在,返回与key所对应的value。
如果key 不存在,返回null。
如果key 是null,抛出Nul LPointerException。
System.out.println(m1.get("apple"));
System.out.println(m1.get("watermelon"));
//System.out.println(m1.get(null));
/*
打印结果:
苹果
null
*/
- V getOrDefault(Object key, V defaultValue) 返回 key 对应的 value,key 不存在,返回默认值:
System.out.println(m1.getOrDefault("apple","苹果手机"));
System.out.println(m1.getOrDefault("watermelon","西瓜"));
System.out.println(m1.size());
System.out.println(m1);
/*
打印结果:
苹果
西瓜
4
{apple=苹果, banana=null, orange=橙子, peach=桃子}
*/
- V remove(Object key) 删除 key 对应的映射关系:
如果key存在,删除该键值对,然后返回该键值对中的value。
如果key不存在,直接返回null。
//remove(key):将Map中key所对应的键值对删除掉。
//如果key存在,删除该键值对,然后返回该键值对中的value
//如果key不存在,直接返回null
System.out.println(m1);
System.out.println(m1.remove("banananaan"));
System.out.println(m1.remove("banana"));
System.out.println(m1);
/*
打印结果:
{apple=苹果, banana=null, orange=橙子, peach=桃子}
null
null
{apple=苹果, orange=橙子, peach=桃子}
*/
- boolean containsKey(Object key) 判断是否包含 key:
时间复杂度O(log2N) 以2为底的N
找key是根据Map底层结构的特性进行比较
if (m1.containsKey("banana")){
System.out.println("banana is in map!!!");
}else {
System.out.println("banana is not in map!!!");
}
/*
打印结果:
banana is in map!!!
*/
- boolean containsValue(Object value) 判断是否包含 value
时间复杂度O(N)
找value实际进行的是整体的遍历
if (m1.containsValue("苹果")){
System.out.println("有");
}else {
System.out.println("没有");
}
if (m1.containsValue("草莓")){
System.out.println("有");
}else {
System.out.println("没有");
}
/*
打印结果:
有
没有
*/
- 打印所有的key,value,键值对:
//打印所有的key
for (String s : m1.keySet()){
System.out.println(s+" ");
}
//打印所有的value
for (String s : m1.values()){
System.out.println(s+" ");
}
//打印所有的键值对
for (Map.Entry<String,String> e : m1.entrySet()){
System.out.println(e.getKey() + "---->" + e.getValue());
}
/*
打印结果:
apple
orange
peach
苹果
橙子
桃子
apple---->苹果
orange---->橙子
peach---->桃子
*/
以上七点均在TreeMap情况下执行,HashMap下执行情况如下:
public static void testHashMap() {
Map<String,String> m1 = new HashMap<>();
m1.put("peach","桃子");//插入键值对
m1.put("orange","橘子");
System.out.println(m1.put("apple","苹果"));
System.out.println(m1.size());
System.out.println(m1);
//验证key是否可以重复
//如果key不存在,将该key-value组成的键值对插入
//如果key存在,使用value替换原key所对应的value
//在插入key-value期间,Map会保证key是一个有序的序列---延伸期间肯定要对key进行比较----->
//延伸:如果key是自定义 类型的元素,该类的对象必须要能够比大小--->实现Comparable接口Comparator
//返回值:如果key不存在,将该键值对插入,返回null
// 如果key存在,用value覆盖原key的value
System.out.println(m1.put("orange","橙子"));
System.out.println(m1.size());
System.out.println(m1);
//key是一定不能为空的,如果为空会抛NullPointerException--->原因:key为空无法进行比较
//m1.put(null,"无名");
//value可以为空
m1.put("banana",null);
System.out.println(m1.size());
System.out.println(m1);
// get(key)
//如果key存在,返回与key所对应的value
//如果key 不存在,返回null
//如果key 是null,抛出Nul LPointerException
System.out.println(m1.get("apple"));
System.out.println(m1.get("watermelon"));
// System.out.println(m1.get(null));
System.out.println(m1.getOrDefault("apple","苹果手机"));
System.out.println(m1.getOrDefault("watermelon","西瓜"));
System.out.println(m1.size());
//remove(key):将Map中key所对应的键值对删除掉。
//如果key存在,删除该键值对,然后返回该键值对中的value
//如果key不存在,直接返回null
System.out.println(m1);
System.out.println(m1.remove("banananaan"));
if (m1.containsKey("banana")){
System.out.println("banana is in map!!!");
}else {
System.out.println("banana is not in map!!!");
}
System.out.println(m1.remove("banana"));
System.out.println(m1);
if (m1.containsValue("苹果")){
System.out.println("有");
}else {
System.out.println("没有");
}
if (m1.containsValue("草莓")){
System.out.println("有");
}else {
System.out.println("没有");
}
//打印所有的key
for (String s : m1.keySet()){
System.out.println(s+" ");
}
//打印所有的value
for (String s : m1.values()){
System.out.println(s+" ");
}
//打印所有的键值对
for (Map.Entry<String,String> e : m1.entrySet()){
System.out.println(e.getKey() + "---->" + e.getValue());
}
}
public static void main(String[] args){
testHashMap();
}
/*
打印结果:
null
3
{orange=橘子, apple=苹果, peach=桃子}
橘子
3
{orange=橙子, apple=苹果, peach=桃子}
4
{orange=橙子, banana=null, apple=苹果, peach=桃子}
苹果
null
苹果
西瓜
4
{orange=橙子, banana=null, apple=苹果, peach=桃子}
null
banana is in map!!!
null
{orange=橙子, apple=苹果, peach=桃子}
有
没有
orange
apple
peach
橙子
苹果
桃子
orange---->橙子
apple---->苹果
peach---->桃子
*/
3.Map的使用
Map是一个接口,必须使用TreeMap或者HashMap来进行实例化。
TreeMap和HashMap:
共同点:都存储的是K-V键值对,都实现了Map接口。
不同点:
TreeMap | HashMap |
---|---|
红黑树 | 哈希桶 |
时间复杂度O(log2N) | 时间复杂度O(1) |
关于key有序 | 不一定有序 |
应用场景:需要key有序 | 应用场景:不关心key是否有序,关心更高的查询效率 |
Set
Set是一个接口,该接口继承了Collection,该接口中只能存放K。
Set只能使用TreeSet和HashSet。
Set里面的key是不能够重复的,TreeSet:去重+排序。HashSet:去重。
Set的常见方法
TreeSet:
public static void testTreeSet(){
Set<String> s = new TreeSet<>();
System.out.println(s.add("orange"));
System.out.println(s.add("peach"));
System.out.println(s.add("apple"));
System.out.println(s.size());
System.out.println(s);
System.out.println(s.add("apple"));
System.out.println(s);
if (s.contains("watermelon")){
System.out.println("在");
}else {
System.out.println("不在");
}
if (s.contains("apple")){
System.out.println("在");
}else {
System.out.println("不在");
}
//遍历
Iterator<String> it = s.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
System.out.println(s.remove("watermelon"));
System.out.println(s.remove("apple"));
s.clear();
}
public static void main(String[] args){
testTreeSet();
}
/*
打印结果:
true
true
true
3
[apple, orange, peach]
false
[apple, orange, peach]
不在
在
apple
orange
peach
false
true
*/
HashSet:
public static void testHashSet(){
Set<String> s = new HashSet<>();
System.out.println(s.add("orange"));
System.out.println(s.add("peach"));
System.out.println(s.add("apple"));
System.out.println(s.size());
System.out.println(s);
System.out.println(s.add("apple"));
System.out.println(s);
if (s.contains("watermelon")){
System.out.println("在");
}else {
System.out.println("不在");
}
if (s.contains("apple")){
System.out.println("在");
}else {
System.out.println("不在");
}
//遍历
Iterator<String> it = s.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
System.out.println(s.remove("watermelon"));
System.out.println(s.remove("apple"));
s.clear();
}
public static void main(String[] args){
testHashSet();
}
/*
打印结果:
true
true
true
3
[orange, apple, peach]
false
[orange, apple, peach]
不在
在
orange
apple
peach
false
true
*/