------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
最近学习了下Map结合类,总结了一下现分享给大家!!!!
一、Map集合
1、Map集合概述---是一个接口
1)Map集合和collection集合接口没有关系
2)Map接口是一个单独接口,使用和collection完全不同的方式管理和存储数据
3)Map存储元素的方式是“键值对”
4)使用collection集合存储时,只是简单的向集合中存储,
取出时:采用数组、迭代器、list集合中还有get的索引方法
5)Map采用起个名字,采用名字映射对象的方法
6)存储的时候,名字和对象一起作为一个单元存储
名字:键(Key);存储对象:值(Value)
2、Map集合的特点
1)Map是双列结构的,并且每个元素是无序
(所谓无序是指存入和取出的顺序没有规律,而不是其内元素的存储无序,其内是采用特殊方法存储的)
2)Map中要求键是唯一,和索引差不多
3)Map集合中的数据结构是针对键的,和值无关的,collection是针对元素有效
4)Map也有size()方法
3、Map接口中基本方法
1)添加方法
V put(K key,V value)向集合中添加元素。如果添加的键,结合已经存在,就会返回旧值,并把新值存入;若是没有定义过就会返回null。
A:这里有个比较的过程,就是比较键。实际上,每调用put方法,就会隐式调用键的对象的hashcode()方法和equals()方法。
所以如果使用自定对象作为键的话,有必要重写其两种方法,不然内容相同的两个所想仍旧会被认为是不同的。
B:直接打印Map类的集合名,可以到大括号{}内部元素逗号分开的样式,是因为HashMap集合继承自AbstractMap,AbstractMap重写了tostring方法.方法如下:
public String toString() {
Iterator> i = entrySet().iterator();
if (! i.hasNext())
return "{}";
StringBuilder sb = new StringBuilder();
sb.append('{');
for (;;) {
Entry e = i.next();
K key = e.getKey();
V value = e.getValue();
sb.append(key == this ? "(this Map)" : key);
sb.append('=');
sb.append(value == this ? "(this Map)" : value);
if (! i.hasNext())
return sb.append('}').toString();
sb.append(',').append(' ');
}
}
2)删除
V remove(Object key)根据某个"键",删除元素;返回被删除的Value
★ 若是删除一个没有定义的键,那么返回null,集合不变化
★ 若是删除一个存储的键,那么集合会发生改变
void clear()清空整个集合
3)判断
boolean contains(Object key)集合是否包含键key,包含返回true,否则返回false
boolean contains(Object value)集合是否包含值value,包含返回true,否则返回false
boolean isEmpty()判断集合是否为空
4)获取功能
int size()获取集合的长度
V get(Object key)根据键获取集合中键所对应的值。若是没有的定义的键其值返回null
Set
Collection
Set
★★★ 5)遍历集合——————》注意使用泛型
A:Set
Set
for(String key : keySet){
String str=(String)map.get(key);//强制转型,注意使用泛型就不用如此了
System.out.println(key + "----" + map.get(key) );}
B:Set
Set
for(Map.Entry
String key = entry.getKey();
String value = entry.getValue();
System.out.println("key = " + key + " value = " + value);}
C:注意泛型的使用规范
二、HashMap集合
1、无序的:线程不安全的,效率高。底层哈希表实现
2、HashMap集合继承自AbstractMap,AbstractMap重写了tostring方法。实现接口Map,可以使用,Map中的方法
3、键和值使用不同类型的对象时
A:键为String,值为String
B:键为String,值为Student
C:键为Student,值为String
注意:使用自定义对象可以做键,但键是不允许重复的,内部判断依赖于对象的hashCode和equals方法,
所以我们自定义对象要做键时,要重写这两个方法。如果不重写,就会有两个相同内容的对象做键。
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
三、linkedHashMap类
1、内部哈希表实现保证唯一,链表实现保证有序
2、线程不安全的。
四、TreeMap类
1、内部使用红黑数结构
2、树结构会对内部“键”进行排序:
自然排序:键所在的类要是要实现comparable接口,并且内部重写compareTo()
比较器排序:集合类要实现comparator接口,并重写compare()方法
3、使用Student类做键,String做值时(使用自然排序)
当往集合中添加元素时,即调用put方法存储时,put方法中会用到compare方法比较存储对象的大小,因此要重写
public class Student implements Comparable {
private String name;
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int compareTo(Student o) {
int n1 = this.name.compareTo(o.getName());//这是实际上还调用了String类的compareto的方法。
int n2 = (n1 == 0 ? this.age - o.getAge() : n1);
return n2;}
可以查看TreeMap 中的put方法原码分析:
public V put(K key, V value) {
Entry t = root;
if (t == null) {
compare(key, key); // type (and possibly null) check
root = new Entry<>(key, value, null);
size = 1;
modCount++;
return null;
}
int cmp;
Entry parent;
// split comparator and comparable paths
Comparator super K> cpr = comparator;
if (cpr != null) {
do {
parent = t;
cmp = cpr.compare(key, t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
else {
if (key == null)
throw new NullPointerException();
Comparable super K> k = (Comparable super K>) key;
do {
parent = t;
cmp = k.compareTo(t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
Entry e = new Entry<>(key, value, parent);
if (cmp < 0)
parent.left = e;
else
parent.right = e;
fixAfterInsertion(e);
size++;
modCount++;
return null;
}