您的位置:首页 > 其它

集合框架-Map

2016-05-25 21:42 387 查看
Map集合

* 1.Map集合中存储的是一对儿元素。键和值。之间存在着对应关系。 * 2.必须要保证键的唯一性。 * 3.如果存储键相同,值会覆盖。

特点:
1,存储的都是键值对。
2,要保证键的唯一性。

存的方式:put(key,value);
取的方式:keySet(),entrySet(),values();
原理:就是将map集合转成set集合或者Collection集合,再通过Iterator取出。

Map
|--Hashtable:哈希表结构,同步的。null不可以作为键和值。
|--HashMap:哈希表结构,不同步的。替代了Hashtable。允许null作为键和值。
|--TreeMap:二叉树结构,不同步的,可以对map集合中的键进行排序。排序需要比较大小。
排序方式有两种:1.元素自身具有比较性

2.容器构造器中传入一个比较器

集合框架-Map-常见方法

put(K key, V value)
将指定的值与此映射中的指定键关联(可选操作)。
返回:
返回与 key 相关联的先前值,如果 key 没有映射关系,则返回 null(返回 null 可能还表示映射以前将 null 与指定键关联)

get(Object key)

返回:
指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null

@Test
public void test1(){
/*
* 需求:将学号和对应的学生姓名进行存储。
*/
Map<Integer,String> map = new HashMap<Integer,String>();
//存储键值对。
System.out.println(map.put(2,"小花"));//之前与 key 关联的值,如果没有针对 key 的映射关系,则返回 null
System.out.println(map.put(2,"麻子"));//小花,麻子之前是小花
map.put(6,"赵六");
map.put(1,"王五");
System.out.println(map);//并没有排序,并且不是有序。2=麻子,“小花”被覆盖
System.out.println(map.get(1));//王五
}
测试结果:
null
小花
{1=王五, 2=麻子, 6=赵六}
王五


集合框架-Map-keySet方法
Set底层用的是Map集合的Key

//    * 获取Map中的所有键值对。
//    * Map取出所有元素的原理:将map先转成set,再使用迭代器。
//    *

@Test
public void test2(){
Map<String,String> map = new HashMap<String,String>();

map.put("zhangsan","北京");
map.put("lisi","上海");
map.put("wangwu","成都");
map.put("zhaoliu","广州");
System.out.println(map);

//第一种方式:
//获取map集合中的键的集合。keySet();
Set<String> keySet = map.keySet();

//通过set集合获取迭代器。
Iterator<String> it = keySet.iterator();

while(it.hasNext()){
String key = it.next();
String value = map.get(key);
System.out.println(key+":"+value);
}
}


集合框架-Map-entrySet方法&values方法

接口 Map.Entry<K,V>。Entry接口是Map接口的内部接口,因为要访问Map接口中的成员变量,所以就定在内部了,而且它和Map的关系是,先有Map接口中的成员变量,之后才有了Entry接口,表示成员变量之间的关系,所以就定在了里面。

@Test
public void test3(){
Map<String,String> map = new HashMap<String,String>();

map.put("zhangsan","北京");
map.put("lisi","上海");
map.put("wangwu","成都");
map.put("zhaoliu","广州");
System.out.println(map);

//第二种方式:
//获取map集合中所有的键值关系集合。entrySet,键值关系的类型是 Map.Entry.

Set<Map.Entry<String, String>> entrySet = map.entrySet();

//迭代器取出所有的关系对象。
Iterator<Map.Entry<String, String>> it = entrySet.iterator();
while(it.hasNext()){

Map.Entry<String, String> me = it.next();
String key = me.getKey();
String value = me.getValue();

System.out.println(key+"::"+value);
}

}
@Test
public void test4(){
Map<String,String> map = new HashMap<String,String>();

map.put("zhangsan","北京");
map.put("lisi","上海");
map.put("wangwu","成都");
map.put("zhaoliu","广州");
System.out.println(map);

//第三种方式:获取值的集合。values();

Collection<String> values = map.values();

Iterator<String> it = values.iterator();
while(it.hasNext()){
String value = it.next();
System.out.println(value);
}

}
Map-HashMap存储自定义对象

package cn.itcast.p1.map;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;

import cn.itcast.bean.Student;

public class HashMapDemo {
public static void main(String[] args) {

/*
* 将学生对象存储和学生的归属地存储到HashMap集合中。
* 对于学生对象,同姓名同年龄视为同一个人。
*/

//1,创建一个HashMap集合对象。
HashMap<Student,String> hm = new HashMap<Student,String>();

//2,将学生对象和归属地存储到集合中。
hm.put(new Student("xiaoming",20),"北京");
hm.put(new Student("abc",20),"成都");
hm.put(new Student("wangcai",20),"广州");
hm.put(new Student("caige",20),"上海");
hm.put(new Student("wangcai",20),"铁岭");

//3,取出map集合中所有的元素。获取Map中键的集合,通过keySet方式。
//Set<Student> keySet = hm.keySet();
//Iterator<Student> it = keySet.iterator();
Iterator<Student> it = hm.keySet().iterator();
while(it.hasNext()){
Student key = it.next();
String value = hm.get(key);
System.out.println(key.getName()+":"+key.getAge()+":"+value);
}
}
}
//比较两个对象是否一样,重写hashcode方法 和 equals方法
package cn.itcast.bean;

public class Student{

private String name;
private int age;

public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}

/**
* 覆盖hashCode方法
* @return
*/
@Override
public int hashCode() {

final int NUMBER = 31;//对31这个数字进行命名定义。增强了阅读性。

return name.hashCode()+age*NUMBER;
}

/**
* 覆盖equals方法
* @return
*/
@Override
public boolean equals(Object obj) {

if(!(obj instanceof Student))
throw new NotTypeException("错误的类型");

Student stu = (Student)obj;
return this.name.equals(stu.name) && this.age == stu.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 String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}


Map-TreeMap存储自定义对象
package cn.itcast.p1.map;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import cn.itcast.bean.Student;
import cn.itcast.p2.comparator.ComparatorByName;

public class TreeMapDemo {

public static void main(String[] args) {

//1,创建TreeMap集合。
//设置比较器,定义排序方式:map的key的排序方式根据对象的name值的自然排序
TreeMap<Student,String> tm = new TreeMap<Student,String>(
new Comparator<Student>(){
@Override
public int compare(Student o1, Student o2) {
int temp = o1.getName().compareTo(o2.getName());
return temp==0?o1.getAge()-o2.getAge(): temp;
}
}
});
tm.put(new Student("xiaoming",26),"北京");
tm.put(new Student("abc",24),"成都");
tm.put(new Student("wangcai",21),"广州");
tm.put(new Student("caige",27),"上海");
tm.put(new Student("wangcai",21),"铁岭");
// 取出集合中的元素。获取Map集合中所以键值关系集合方法entrySet()
//Set<Map.Entry<Student,String>> entrySet = tm.entrySet();
//Iterator<Map.Entry<Student,String>> it = entrySet.iterator();
Iterator<Map.Entry<Student,String>> it = tm.entrySet().iterator();
while(it.hasNext()){
Map.Entry<Student, String> me = it.next();
Student key = me.getKey();
String value = me.getValue();
System.out.println(key.getName()+"::"+key.getAge()+"::"+value);
}
}

}


Map-什么时候用Map
* 什么时候用map集合?
* 在分析需求中,如果出现了映射关系,就要先想到具备对应关系的容器。
* 比如 数组,list,map。
* 如果对应关系的一方是有序的数字,可以考虑数组和list,元素固定考虑数组,不固定考虑list。
* 如果对象关系的一方没有有序的数字,就要想到map。
*
* 通常这些对应关系的容器都可以用于查表法。

package cn.itcast.test;

import java.util.HashMap;
import java.util.Map;

public class Test {

public static void main(String[] args) {
String week = getCnWeek(3);
String enweek = getEnWeek(week);
System.out.println(week);
System.out.println(enweek);
}

/**
* 通过中文获取英文。
* @param num
* @return 返回的是cnweek参数对应的英文表示方式。
* 如果没有对应返回 null。
*/
public static String getEnWeek(String cnweek){
/*
* 创建一个表。存储中英对应星期。
*/
Map<String,String> weekMap = new HashMap<String,String>();
weekMap.put("星期一", "Monday");
weekMap.put("星期二", "Tuesday");
weekMap.put("星期三", "Wednesday");
weekMap.put("星期四", "Thursday");
weekMap.put("星期五", "Friday");
weekMap.put("星期六", "Saturday");
weekMap.put("星期日", "Sunday");
return weekMap.get(cnweek);
}

public static String getCnWeek(int num){
//定义一个表。
String[] weeks = {"","星期一","星期二","星期三","星期四","星期五","星期六","星期日"};
return weeks[num];
}
}


Map-练习-字母次数
/*作业:
* "ert+yuiodf8g.hjkt"想要知道每个字母出现的次数。
* a(3)b(5)c(1)e(6).....友情提示:当需求中有对应关系时,先要考虑map集合。
*
* 思路:
* 1,字母很多,必须要进行存储。存储就需要使用容器。
* 2,哪个容器呢?数组,不合适,长度不确定。StringBuffer,不合适,要对单个字母操作。
*    Collection,好像也不太合适,存储了字母后,次数咋办?
* 3,发现字母和次数之间存在着对应关系,所以可以使用map集合。
* 具体用哪个子类对象呢?发现要求的结果中abc等出现是有顺序的。所以可考虑使用TreeMap。
* 4,map集中,存储的就是字母和对应的次数,字母作为键。map作为表。
*   将字符串中的每一个字母都去查表。如果该字母没查找对应的次数,就将该字母和1存储到表中。
*   如果查到次数,将次数加+1后,将该字母和次数存储到表中。
*
*/

package cn.itcast.test;

import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;

public class Test2 {
public static void main(String[] args) {
String str = "erAt+yuAeioCrdCfe8g.hyjkt";
str = sortChar(str);
System.out.println(str);

}

public static String sortChar(String str){

//1,定义一个存储字母和次数的表。TreeMap.
Map<Character,Integer> map = new TreeMap<Character,Integer>();

//2,将字符串转成字符数组。
char[] chs = str.toCharArray();

//3,对数组进行遍历。
for(int x=0; x<chs.length; x++){

if(!isLetter(chs[x])){
continue;//不是字母,回去循环,下面的语句不要执行
}
//将遍历到的字符作为键。去查表。获取对应的次数。
Integer value = map.get(chs[x]);
int count = 0;
if(value!=null){
count = value;
}
count++;

//将字母和对应的次数存储到map集合中。
map.put(chs[x], count);

}

return mapToString(map);

}

/*
* 将map集合转成指定格式的字符串。键(值)键(值)....
*/
private static String mapToString(Map<Character, Integer> map) {

//元素很多,最终要变成字符串。废话吗?不用废话,StringBuilder正好ok。
StringBuilder sb = new StringBuilder();

//遍历map。
Iterator<Map.Entry<Character, Integer>> it = map.entrySet().iterator();

while(it.hasNext()){

Map.Entry<Character, Integer> me = it.next();

Character key = me.getKey();
Integer value = me.getValue();

//StringBuilder的增加字符串的方法append()
sb.append(key+"("+value+")");
}

return sb.toString();
}

/*
* 判断字符是否是字母。
*/
private static boolean isLetter(char c) {

return c>='a' && c<='z' || c>='A' && c<='Z';
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: