一、Map
—Hashtable:底层是哈希表数据结构,不可以存入null键null值,该集合是线程同步的JDK1.0
—-HashMap:底层是哈希表数据结构,允许使用null键null值,该集合不同步JDK1.2
—–TreeMap:底层是二叉树数据结构,线程不同步。可以用于给map集合中的键进行排序。
与Set很像。Set底层就是使用了Map集合
接口:Map
public static void main(String[] args) {
// TODO Auto-generated method stub
Map<String,String> map=new HashMap<String ,String>();
//添加元素:如果出现相同的键,那么后添加的值会覆盖原来的值,并且put返回被覆盖的值
sop(map.put("01", "zhangsan1"));//put自带返回值,返回该键对应的之前的值,在之前没有在01存过值,所以返回null
sop(map.put("01", "aaaaa"));//在键01处,在之前存过了zhangsan1值,所以输出zhangsan01
map.put("02", "zhangsan2");
map.put("03", "zhangsan3");
sop("-----------------------");
//判断
System.out.println("containsKey:"+map.containsKey("022"));//false
//删除
//System.out.println("remove"+map.remove("01"));//从哈希表中移除该键及相应的值
//获取
System.out.println("get:"+map.get("02"));//可以通过get的返回值来判断一个键是否存在,若不存在,返回null
System.out.println("get:"+map.get("01"));//不存在,返回空
//获取map中的所有值public Collection<V> values()
Collection<String> coll=map.values();
Iterator<String> it=coll.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
获取所有的键值对方法一:
//获取所有的键值对:Set<K> keySet(),将键都存入Set集合中,在Set中有迭代器,再根据get(key)获得值
Set<String> s=map.keySet();
Iterator<String> it1=s.iterator();
while(it1.hasNext()) //while内部只能有一个it.next,否则出现安全隐患
{
String str=it1.next();
System.out.println("键: "+str+" 值:"+map.get(str));
}
在map中无论是键还是值,都是引用,在但是为了看的比较方便直接将具体的数值进行演示,通过keySet方法得到了键的值,依据键值对,再根据get(key)就可以得到值了
获取所有的键值对方法一:
//获取所有的键值对的方法二:Set<Map.Entry<K,V>> entrySet()
Set<Map.Entry<String, String>> s1=map.entrySet();
Iterator<Map.Entry<String, String>> it2=s1.iterator();
while(it2.hasNext()) {
Map.Entry<String, String> me=it2.next();//迭代器什么类型,it.next就是什么类型,这个对象一定是Map.Entry的子类,所以Map.Entry接口可以接收这个对象
sop("键:"+me.getKey()+" 值:"+me.getValue());//要获得关系中的键和值,就要看这个类中的方法,也就是Map.Entry中的方法,这两个方法是Map.Entry接口中的方法
}
Map.Entry:其实Entry也是一个接口,它是Map接口的一个内部接口
interface Map
{
public static interface Entry{
public abstract Object getKey();
public abstract Object getValue();
}
}
class HashMap implement Map{
class Hahaimplement Map.Entry
public abstract Object getKey(){};
public abstract Object getValue(){};
}
若理解不了,就把Map.Entry当成数据类型就可以了
练习:每个学生都有对应的归属地
学生Student:地址String
学生属性:姓名,年龄。
注意:姓名和年龄相同视为同一个学生,保证学生的唯一性。
public class Studnt implements Comparable<Studnt> {
private String name;
private int age;
Studnt(String name,int age){
this.age=age;
this.name=name;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
//toString这个方法很常见,所以覆盖写上
public String toString() {
return name+"-----"+age;
}
//学生类可能存入哈希中,所以要实现hashCode、equals方法
//只要哈希,就得写这两个方法,无论HashSet、HashMap只要与哈希有关
public int hashCode() {
return name.hashCode()+age*23;
}
public boolean equals(Object obj) {
if(!(obj instanceof Studnt))
throw new ClassCastException("类型转换不匹配");//运行时异常,不用声明
Studnt stu=(Studnt)obj;
if (this.name==stu.name&this.age==stu.age)
return true;
return false;
}
//学生类对象也可能存入二叉树中,所以要实现Comparable接口,实现compareTo方法
public int compareTo(Studnt stu) {
int num=new Integer(this.age).compareTo(new Integer(stu.age));
if(num==0)
return this.name.compareTo(stu.name);
else
return num;
}
}
public class StudntDemo {
public static void sop(Object obj) {
System.out.println(obj);
}
public static void main(String[] args) {
Map<Studnt,String> map=new HashMap<Studnt,String>();
map.put(new Studnt("zhangsan01",12), "addr01");
map.put(new Studnt("zhangsan02",12), "addr02");
map.put(new Studnt("zhangsan03",12), "addr03");
map.put(new Studnt("zhangsan01",12), "addr00000");
//注意当第二个"zhangsan01",12进入前,先判断了其为重复元素,不存入,但是其值修改为新的addr00000000
sop("------------第一种方式取出-------------");
Set<Studnt> s=map.keySet();
Iterator<Studnt> it=s.iterator();
while(it.hasNext()) {
Studnt stu=it.next();
sop("姓名:"+stu.getName()+" 地址:"+map.get(stu));
}
sop("------------第二种方式取出-------------");
Set<Map.Entry<Studnt, String>> se=map.entrySet();
Iterator<Map.Entry<Studnt, String>> it1=se.iterator();
while(it1.hasNext()) {
Map.Entry<Studnt, String> me=it1.next();
sop("姓名:"+me.getKey().getName()+" 地址:"+me.getValue());
}
}
}
①创建的是HashMap集合,则自动调用hashcode、equals方法,来保证元素的唯一性。
②若创建TreeMap集合,则可直接将HashMap改为TreeMap即可,就会自动调用compareTo方法,进行排序,重复年龄按照第二关键字来排序,来保证元素的唯一性。
③若想要按照姓名排序,因为已经有了compareTo方法,所以要创建比较器,然后再创建集合时,加入比较器对象参数即可。
代码如下:
public class MyComp implements Comparator<Studnt>{
public int compare(Studnt stu1,Studnt stu2) {
int num=stu1.getName().compareTo(stu2.getName());
if(num==0) {
return new Integer(stu1.getAge()).compareTo(new Integer(stu2.getAge()));
}
else
return num;
}
}
主函数部分的改动为:TreeMap<Studnt,String> map=new TreeMap<Studnt,String>(new MyComp());