Java基础-集合
集合进阶2
1、集合(Map概述)
Map集合:该集合存储键值对,一对一对往里存,而且要保证键的唯一性。 (1)、添加:
V put(K key, V value);//将指定的值与此映射中的指定键关联(可选操作)。
void putAll(Map<? extends K,? extends V> m);//从指定映射中将所有映射关系复制到此映射中(可选操作)。
(2)、删除:
void clear();//从此映射中移除所有映射关系(可选操作)。
V remove(Object key);//如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。
(3)、判断:
boolean containsKey(Object key);//如果此映射包含指定键的映射关系,则返回 true。
boolean containsValue(Object value);//如果此映射将一个或多个键映射到指定值,则返回 true。
(4)、获取:
V get(Object key);//返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。用来配合keySet方法使用,下面会讲解
int size();//返回此映射中的键-值映射关系数。
Collection<V> values();//返回此映射中包含的值的 Collection 视图。
2、集合(Map子类对象特点)
Map结构
|----Hashtable
|---HashMap
|---TreeMap
Map结构特点
|----Hashtable:底层是哈希表数据结构,不可以存入null键和null值,该集合是线程同步,jdk1.0,低效。
|----HashMap:底层是哈希表数据结构,允许使用null键和null值,集合不同步,jdk1.2,高效。
|----TreeMap:底层是二叉树 数据结构,线程不同步,可以用于给map集合中的键进行排序,和Set很像,其实Set底层就是使用Map集合。
3、集合(Map共性方法)
import java.util.*;
class HashMapDemo1
{
public static void main(String [] args)
{
Map <String ,String > hashmap = new HashMap<String ,String >();
//添加元素,如果出现添加时,相同的键,那么后添加的值会覆盖原有键对应的值,并put方法会返回被覆盖的值。
hashmap.put("01","zhangsan01");
hashmap.put("02","zhangsan02");
hashmap.put("03","zhangsan03");
System.out.println("containsKey:"+hashmap.containsKey("022"));
System.out.println("get:"+hashmap.get("023"));
hashmap.put("04","null");
System.out.println("get:"+hashmap.get("04"));
//可以通过get方法的返回值来判断一个键是否存在,通过返回null来判断。
System.out.println(hashmap);
//获取hashmap集合中的所有的值。
Collection <String > coll = hashmap.values();
System.out.println(coll);
System.out.println(hashmap);
}
}
输出:
4、集合(Map-keySet)
map集合的两种取出方式:
(1)、keySet:将map中所有的键存入到Set集合,因为Set具备迭代器,所以可以迭代方式取出所有的键,在根据get方法,获取每一个键的对应值。
import java.util.*;
class HashMapDemo2
{
public static void main(String [] args)
{
Map <String ,String > hashmap = new HashMap<String ,String >();
//添加元素,如果出现添加时,相同的键,那么后添加的值会覆盖原有键对应的值,并put方法会返回被覆盖的值。
hashmap.put("01","zhangsan01");
hashmap.put("02","zhangsan02");
hashmap.put("03","zhangsan03");
hashmap.put("04","zhangsan04");
//先获取map集合的所有键Set集合:keySet();
Set<String > keySet = hashmap.keySet();
//有了Set集合,就可以获取迭代器。
Iterator<String> it = keySet.iterator();
while(it.hasNext())
{
String key = it.next();
String value = hashmap.get(key);
System.out.println("key:"+key+",value:"+value);
}
}
}
输出:
示意图:
5、集合(Map-entrySet)
总结上一节:
1、Map集合的取出原理:将map集合转成Set集合,通过迭代器取出。
2、Set<Map.Entry<K,V>> entrySet:将Map集合中的映射关系存入到了Set集合中,而这个关系的数据类型是Map.Entry。
Demo
import java.util.*;
class HashMapDemo3
{
public static void main(String [] args)
{
Map <String ,String > hashmap = new HashMap<String ,String >();
//添加元素,如果出现添加时,相同的键,那么后添加的值会覆盖原有键对应的值,并put方法会返回被覆盖的值。
hashmap.put("01","zhangsan01");
hashmap.put("02","zhangsan02");
hashmap.put("03","zhangsan03");
hashmap.put("04","zhangsan04");
//将Map集合中的映射关系取出,存入到Set集合中。
Set<Map.Entry<String ,String >> entrySet = hashmap.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:" +key+",value:"+value);
}
}
}
输出:
示意图:
- Map.Entry中的Entry也是一个接口,它是Map借口中的一个内部接口。
demo
interface Map
{
public static interface Entry
{
public abstract Object getKey();
public abstract Object getValue();
{
}
class HashMap implements Map
{
class Hash implements Map.Entry
{
public Object getKey(){}
public Object getValue(){}
}
}
6、集合(Map练习)
每一个学生都有对应的归属地。 学生Student,地址String 学生属性:姓名,年龄 注意:姓名和年龄相同视为同一个学生。 保证学生的唯一性。
思想:
1、描述学生。
2、定义Map容器,将学生作为键,地址作为值,存入。
3、获取map集合中的元素。
demo
import java.util.*;
class Student implements Comparable<Student>
{
private String name;
private int age;
public Student (String name,int age)
{
this.name = name;
this.age = age;
}
public int compareTo(Student s )
{
int num = new Integer(this.age).compareTo(s.age);
if(num == 0)
{
return this.name.compareTo(s.name);
}
return num ;
}
public int hashCode()
{
return name.hashCode()+age*34;
}
public boolean equals(Object obj)
{
if(!(obj instanceof Student))
{
throw new ClassCastException("类型不匹配!");
}
Student s= (Student)obj;
return this.name.equals(s.name) && this.age == s.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public String toString ()
{
return name+":"+age;
}
}
class MapTest
{
public static void main(String [] args)
{
HashMap <Student,String> hm = new HashMap<Student , String >();
hm.put(new Student("lisi1",21),"beijing ");
hm.put(new Student("lisi2",19),"henan ");
hm.put(new Student("lisi3",41),"jiangsu ");
hm.put(new Student("lisi4",31),"zhenzhou ");
//第一种取出方式:keySet
Set<Student> keySet = hm.keySet();
Iterator<Student> it = keySet.iterator();
while(it.hasNext())
{
Student stu = it.next();
String addr = hm.get(stu);
System.out.println("name:"+stu.getName()+",age:"+stu.getAge()+",addr:"+addr);
}
//第二种取出方式:entrySet
Set<Map.Entry<Student,String >> entrySet = hm.entrySet();
Iterator<Map.Entry<Student,String >> iter = entrySet.iterator();
while(iter.hasNext())
{
Map.Entry<Student,String > me = iter.next();
Student stu = me.getKey();
String addr = me.getValue();
System.out.println("学生名;"+stu.getName()+",年龄:"+stu.getAge()+",地址:"+addr);
}
}
}
输出:
7、集合(TreeMap练习)
需求:对学生对象的年龄进行升序排序,因为数据是以键值对形式存在的,所以要使用可以排序的Map集合。TreeMap。
import java.util.*;
class Student implements Comparable<Student>
{
private String name;
private int age;
public Student (String name,int age)
{
this.name = name;
this.age = age;
}
public int compareTo(Student s )
{
int num = new Integer(this.age).compareTo(s.age);
if(num == 0)
{
return this.name.compareTo(s.name);
}
return num ;
}
public int hashCode()
{
return name.hashCode()+age*34;
}
public boolean equals(Object obj)
{
if(!(obj instanceof Student))
{
throw new ClassCastException("类型不匹配!");
}
Student s= (Student)obj;
return this.name.equals(s.name) && this.age == s.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public String toString ()
{
return name+":"+age;
}
}
class MapTest1
{
public static void main(String [] args)
{
TreeMap<Student,String > tm = new TreeMap<Student, String >(new StrNameComparator());
tm.put(new Student("blisi3",23),"nanjing");
tm.put(new Student("lisi1",21),"beijing");
tm.put(new Student("alisi4",24),"wuhan");
tm.put(new Student("lisi1",21),"tianjing");
Set<Map.Entry<Student ,String >> entrySet = tm.entrySet();
Iterator<Map.Entry<Student ,String >> iter = entrySet.iterator();
while(iter.hasNext())
{
Map.Entry<Student ,String > me = iter.next();
String addr = me.getValue();
Student stu = me.getKey();
System.out.println("学生名;"+stu.getName()+",年龄:"+stu.getAge()+",地址:"+addr);
}
}
}
class StrNameComparator implements Comparator<Student>
{
public int compare (Student s1 , Student s2)
{
int num = s1.getName().compareTo(s2.getName());
if (num ==0)
{
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
}
return num ;
}
}
输出:
8、集合(TreeMap练习-字母出现的次数)
练习: "adfgzxcvasdfxcvdf"获取该字符串中的字母出现的次数,希望打印结果是:a(1)c(2).....
思考:通过结果发现,每一个字母都存在对应的次数,说明字母和次数之间都有映射关系。注意了,当发现有映射关系时,可以选择map集合,因为map集合中存放就是映射关系。
什么时候使用map集合呢? 当数据之间存在这映射关系时,就要先想map集合。
如图所示:
思路:
1、将字符串转换成字符数组,因为要对每一个字母进行操作。
2、定义一个map集合,因为打印结果的字母有顺序,所以使用treemap集合。
3、遍历字符数组:将每一个字母作为键去查map集合,如果返回null,将字母和1存入到map集合中,如果返回不是null,说明该字母在map集合已经存在并有对应的次数。那么就获取该次数并进行自增,然后将该字母和自增后的次数存入到map的集合中,覆盖调用原来键所对应的值。
4、将map集合中的数据变成指定的字符串形式返回。
测试代码:
import java.util.*;
class MapTest3
{
public static void main(String [] args)
{
String s = charCount("ak+abflc,dkabc_defa");
System.out.println(s);
}
public static String charCount(String str)
{
char [] chs = str.toCharArray();
TreeMap<Character,Integer> tm = new TreeMap<Character , Integer>();
int count = 0;//计数器
for(int x = 0;x<chs.length;x++)//遍历字符数组并存储到TreeMap集合中
{
if(!(chs[x]>='a'&&chs[x]<='z'||chs[x]>='A'&&chs[x]<='Z'))
{
continue;
}
Integer value = tm.get(chs[x]);
if(value!= null)
{
count = value;
}
count++;
tm.put(chs[x],count);
count = 0;//清零
}
StringBuilder sb = new StringBuilder ();//提取treeMap集合中的数据
Set<Map.Entry<Character,Integer>> entrySet = tm.entrySet();
Iterator<Map.Entry<Character,Integer>> it = entrySet.iterator();
while (it.hasNext())
{
Map.Entry<Character,Integer> me = it.next();
Character ch = me.getKey();
Integer value = me.getValue();
sb.append(ch+"("+value+")");
}
return sb.toString();
}
}
输出结果:
9、集合(Map扩展)
map知识扩展 map集合被使用是因为具备映射关系 "yureban" "01" "zhangsan" "yureban" "01" "lisi" "jiuyeban" "02" "wangwu" "jiuyeban" "02" "zhaoliu"
一个学校有多个教室,每一个教室都有一个名称。
import java.util.*;
class MapTest4
{
public static void main(String [] args)
{
HashMap<String,HashMap<String,String>> czbk = new HashMap<String,HashMap<String,String>>();
HashMap<String,String> yure = new HashMap<String,String>();
HashMap<String,String> jiuye = new HashMap<String,String>();
czbk.put("yureban",yure);
czbk.put("jiuyeban",jiuye);
yure.put("01","zhangsan");
yure.put("02","lisi");
jiuye.put("01","zhaoliu");
jiuye.put("02","wangwu");
//遍历czbk集合,获取所有的教室
Set<String> keySet = czbk.keySet();
Iterator<String> it = keySet.iterator();
while(it.hasNext())
{
String roomName = it.next();
HashMap<String,String> room = czbk.get(roomName);
System.out.println(roomName);
getStudentInfo(room);
}
}
public static void getStudentInfo(HashMap<String,String>roomMap)
{
Set<String> keySet = roomMap.keySet();
Iterator<String> it = keySet.iterator();
while(it.hasNext())
{
String id = it.next();
String name = roomMap.get(id);
System.out.println(id+":"+name);
}
}
}
输出: