Map集合
1.特点:
- Map 集合中存放"键-值对" ( “key-value pair” ),键值对也被称作映射项。
- Map 集合中不能包含重复的键 ,但可以包含重复的值。
- Map 集合中一个键只能对应一个值。( 即一个键只能映射到一个值,不能映射到多个值 )
- Map接口的核心:
public interface Map<K, V> {
// 省略 Map 接口中的其它方法
interface Entry<K, V> { // 映射项 ( 内部包含了 键 和 值 )
K getKey();
V getValue();
V setValue(V value);
boolean equals(Object o);
int hashCode();
// 省略 Entry 接口中的其它方法
}
// 省略 Map 接口中的其它方法
}
Map 接口内部内部声明的 Entry 接口表示 映射项 ( item ) ,即前文所说的 键-值对 对应的对象的类型。
在 HashMap 类内部,提供了 Map.Entry 接口的一个实现类:
static class Node<K,V> implements Map.Entry<K,V> { // Node 类是 HashMap 类的静态内部类
final int hash;
final K key;
V value;
Node<K,V> next;
Node( int hash , K key , V value , Node<K,V> next ) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
public final K getKey() { return key; }
public final V getValue() { return value; }
public final String toString() { return key + "=" + value; }
public final int hashCode() {
return Objects.hashCode(key) ^ Objects.hashCode(value);
}
public final V setValue(V newValue) {
V oldValue = value;
value = newValue;
return oldValue;
}
public final boolean equals(Object o) {
if (o == this)
return true;
if (o instanceof Map.Entry) {
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
if (Objects.equals(key, e.getKey()) &&
Objects.equals(value, e.getValue()))
return true;
}
return false;
}
}
2.方法:
3.程序
- 程序一
运行结果:
- 程序二:
public class Goods {
private Integer id;
private String name;
private double price;
public Goods(Integer id, String name, double price) {
super();
this.id = id;
this.name = name;
this.price = price;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
long temp;
temp = Double.doubleToLongBits(price);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object o ) {
if( this == o ) {
return true ;
}
if( o instanceof Goods ) {
Goods another = (Goods) o ;
if( this.id != null && this.id.equals( another.id ) &&
this.name != null && this.name.equals( another.name ) &&
this.price == another.price ) {
return true ;
}
}
return false;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
- 程序三
import java.util.HashMap;
import java.util.Map;
/**
* Map 接口中的 put 方法: <br>
* 1、将 指定的 value 跟 指定的 key 关联 <br>
* 2、如果在 Map 集合中已经存在指定的 key ,则使用 新的 value 替换 旧的 value 并返回 旧的 value <br>
* 3、如果在 Map 集合中 不存在指定的 key ,则使用 直接将 key-value 对放入 Map 集合,返回 null <br>
*/
public class MapTest1 {
public static void main(String[] args) {
// Map<Key,Value>
Map<String,Double> map = new HashMap<>();
// put( K key , V value ) : 将指定的值 ( value ) 与此映射中的指定键 ( key ) 关联
Double v = map.put( "王某" , 48.5 ); // 创建 Map.Entry 实例,其中包含了 key 和 value
System.out.println( v );
v = map.put( "王某" , 50.0 ) ;
System.out.println( v );
System.out.println( map );
System.out.println( map.get( "王某" ) );
System.out.println( map.remove( "王某" ) );
System.out.println( map );
}
运行结果:
- 程序四:
/**
* Map 接口中的 put 方法: <br>
* 1、将 指定的 value 跟 指定的 key 关联 <br>
* 2、如果在 Map 集合中已经存在指定的 key ,则使用 新的 value 替换 旧的 value 并返回 旧的 value <br>
* 3、如果在 Map 集合中 不存在指定的 key ,则使用 直接将 key-value 对放入 Map 集合,返回 null <br>
*
* Map 接口中的 get 方法: <br>
* 1、根据 key 获取 相应的 value ( 根据 key 找到 相应的 Entry 对象 后再获取 value )
* 2、如果根据 key 找到了相应的 映射项(键值对),则直接返回该 映射项 中的 value
* 3、如果未找到 key 对应的 映射项,则直接返回 null
*/
public class MapTest2 {
public static void main(String[] args) {
Map<String,Long> map = new HashMap<>();
System.out.println( "size : " + map.size() + " , is empty : " + map.isEmpty() );
map.put( "张三丰" , 19812344321L );
map.put( "张翠山" , 19812344322L );
map.put( "殷素素" , 16610010001L );
map.put( "张无忌" , null );
map.put( null , null );
System.out.println( map.get( "张三丰" ) );
System.out.println( map.get( "张无忌" ) );
}
运行结果:
- 程序五:
/**
* * 迭代 Map 集合的方法三: 使用 键值对集 ( 所有的 键值对(映射项) 组成的 集合 ) (重要程度: * * * * * ) <br>
* 1、使用 Map 接口声明的 entrySet 方法返回 键值对集 ( 映射项 集合 ) ( 因为 Map 集合中不能包含重复键,所以这个集合中没有重复的元素 )
* 2、根据 键值对集 ( Set < Map.Entry > ) 获得一个迭代器 : Iterator< Map.Entry<String,Integer> > itor = es.iterator() ;
* 3、使用 迭代器 ( itor ) 迭代 键值对集 ( es ) ,并从 entry 实例中直接获取 key 和 value
*/
public class MapTest8 {
public static void main(String[] args) {
Map<String,Integer> map = new HashMap<>();
map.put( "张三丰" , 108 );
map.put( "张翠山", 36 );
map.put( "殷素素" , 34 ) ;
map.put( "张无忌" , 10 );
map.put( "周芷若" , 10 ) ;
// 确定 Set 集合中存放的是 Map.Entry 类型的数据 ( Entry 是 Map 接口的内部接口 )
// 确定 Map.Entry 实例中 Key 的类型为 String , Value 的类型是 Integer
Set< Map.Entry<String,Integer> > es = map.entrySet(); // 返回 map 集合内部 所有的 映射项( Entry ) 组成的集合 ( 就是 键-值对 组成的集合 )
// 获得用来 迭代 entrySet 集合 的 迭代器
Iterator< Map.Entry<String,Integer> > itor = es.iterator() ;
// 使用迭代器 ( itor ) 迭代 entrySet 集合 ( es )
while( itor.hasNext() ) {
Map.Entry<String, Integer> entry = itor.next();
System.out.println( entry.getKey() + " : " + entry.getValue() );
}
}
运行结果: