黑马程序员---java基础------------------集合框架2---Map
Map<k,v>:键值对的映射关系,键是唯一的。
|--hashMap:底层是hi哈希表数据表结构,可以存入null值null键,不同步的(1.2),效率高。
|--hashtable:底层是哈希表数据结构,不可以存入null值null键,同步的(1.0)
|--treeMap:底层是二叉树,线程不同步,可以用于给Map集合中的键排序。
Map的共性方法:
1:添加:
put(k,v)
putAll(Map<? extends k,<? extends v>m)
2:删除:
clear()
3:判断:
containsKey(Object key)
containsValue(Object Value)
isEmpty()
4:获取:
get(Object key)
size()
values()
entrySet()
keySet()
import java.util.*;
class Demo
{
public static void main(String[] args)
{
Map<String,String> map=new HashMap<String,String>();
map.put("01","zhangsan1");//添加时相同的键,后添加的值,后添加会覆盖原有的值,并put方法会返回被覆盖的值
map.put("02","zhangsan2");
map.put("03","zhangsan3");
System.out.println(map.containsKey("012")); //false
System.out.println(map.remove("02")); //返回(删除后)zhangsan2
System.out.println(map.get("01")); //获取zhangsan1,可以用返回值来判断一个键是否存在,通过返回null来判断
map.put("04",null); //添加成功,但是hashtable是不可以的
Collection<String> coll = map.values();
System.out.println(coll); //[null,zhangsan1,zhangsan3]
}
}
import java.util.*;
class Demo {
public static void main(String[] args) {
//通过拿到所有的键拿到所有的值,他没有迭代器keySet(),set也就是集合, //它具备迭代器,可以用迭代去除所有的键,再获取值
Map<String,String> map=new HashMap<String,String>();
map.put("01","zhangsan1");map.put("04","zhangsan2"); map.put("02","zhangsan2"); map.put("03","zhangsan3");
Set<String> keyset=map.keySet();
Iterator<String> it=keyset.iterator();
while(it.hasNext()) {
String key=it.next();
String values=map.get(key);
System.out.println(key+"::"+values); }
//Set<Map.Entry<k,v>> entrySet,取出的第二种方式,它取出的是映射关系返回的是Map.Entry
Set<Map.Entry<String,String>> entrySet=map.entrySet(); //也是返回一个SEt集合
Iterator<Map.Entry<String,String>> it1=entrySet.iterator();
while(it1.hasNext()) {
Map.Entry<String,String> me=it1.next();//看API这个对象Map.Entry锁对应的类型
String key=me.getKey();
String values=map.get(key);
System.out.println(key+"::"+values);
}
}
}
练习:将学生对象存储到集合中,同名同年龄为一个学生,如果是存在哈希表结构中会怎么样,存在二叉树结构中的情况
import java.util.*;
class Student implements compareable<Student>
{
private String name;
private int age;
Student(String name,int age)
{
this.name=name;
this.age=age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public String toString()
{
return name+"::"+age;
}
/*这种情况是存在哈希表结构集合中*/
public int hashCode()
{
return name.hashCode()+age*32;//age乘以一个数是保证了hash值的唯一性
}
public boolean equals(Object obj)
{
if(!(obj instansOf Student))
throw new ClassCastException("类型转换异常");
Student s= (Student)obj;
return this.name.equals(s.name) && this.age=s.age;
}
/*这种情况是存在二叉树集合中,要让它具备自然顺序,要实现compareable*/
public int compareaTo(Student s)
{
int num=new Integer(this.age).compareTo (new Integer(s.age));
if(num==0)
return this.name.compareTo(s.name);
return num;
}
class MapTest
{
public static void main(String[] args)
{
HashMap<Student,String> hm=new HashMap<Studeng,String>
hm.put(new Student("lisi1",21),"beijin");
hm.put(new Student("lisi2",22),"shanghai");
hm.put(new Student("lisi2",22),"shanxi");//键不唯一但是复写了上面的两个方法还是可以的
hm.put(new Student("lisi3",23),"tianjin");
hm.put(new Student("lisi4",24),"wuhan");
//第一种取出方式
Set<Student> keySet=hm.keySet();
Iterator<Student> it=keySet.iterator();
while(it.hasNext())
{
Student stu=it.next();
String adrr=hm.get(stu);
System.out.println(stu+"::"+adrr);
}
//第二种取出方式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 adrr=hm.get(stu);
System.out.println(stu+"::"+adrr);
}
}
}
class MapTest2 //这个方法可以实现自然排序
{
public static void main(String[] args)
{
TreeMap<Student,String> tm=new TreeMap<Studeng,String>
tm.put(new Student("lisi1",21),"beijin");
tm.put(new Student("lisi2",22),"shanghai");
hm.put(new Student("lisi2",22),"shanxi");//键不唯一但是复写了上面的两个方法还是可以的
tm.put(new Student("lisi3",23),"tianjin");
tm.put(new Student("lisi4",24),"wuhan");
//第二种取出方式entrySet
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();
Student stu=me.getkey();
String adrr=hm.get(stu);
System.out.println(stu+"::"+adrr);
}
}
}
//自定义个按姓名排序的比较器,传给调用函数
class StuNameComparator implements Comparator<Student>
{
public int compare(Student s1,Student s2)
{
int num=s1.getName().comparaTo(s2.getName());//姓名比较相同的情况下,砸U按次要条件年龄排序,如果年龄还相等就不能添加
if(num==0)
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
return num;
}
}
map集合的扩展:集合嵌套:传智播客和班级是个集合,班级和学生又是一个集合
集合工具类:
Collection是集合框架中的一个顶层接口,它里面定义了单列集合的共性方法。它有两个常用的子接口,List:对元素都有定义索引。有序的。可以重复元素。Set:不可以
重复元素。无序。
Collections是集合框架中的一个工具类。该类中的方法都是静态的提供的方法中有可以对list集合进行排序,二分查找等方法。通常常用的集合都是线程不安全的。因为要提
高效率。如果多线程操作这些集合时,可以通过该工具类中的同步方法,将线程不安全的集合,转换成安全的。
Collection接口中的toArray方法
指定类型的数组到底要定义多长呢?:当指定类型的数组长度小于了集合的size,那么该方法内部会创建一个新的数组。长度为集合的size。当指定类型的数组长度
大于了集合的size,就不会新创建了数组。而是使用传递进来的数组。所以创建一个刚刚好的数组最优。
为什么要将集合变数组?:为了限定对元素的操作。不需要进行增删了。
ArrayList<String> al = new ArrayList<String>();
al.add("abc1"); al.add("abc2"); al.add("abc3");
String[] arr = al.toArray(new String[al.size()]);
asList:将数组变成list集合
把数组变成list集合有什么好处?:可以使用集合的思想和方法来操作数组中的元素。 注意:将数组变成集合,不可以使用集合的增删方法,因为数组的长度是固
定的。否则会发生UnsupportedOperationException。
如果数组中的元素都是对象。那么变成集合时,数组中的元素就直接转成集合中的元素。如果数组中的元素都是基本数据类型,那么会将该数组作为集合中
的元素存在。
String[] arr = {"abc","cc","kkkk"};
List<String> list = Arrays.asList(arr); //这边都是有泛型的
增强for循环:只能获取集合元素。但是不能对集合进行操作。
for(数据类型 变量名 : 被遍历的集合(Collection)或者数组)
{
}
ArrayList<String> al = new ArrayList<String>(); al.add("abc1"); al.add("abc2"); al.add("abc3");
for(String s : al)
{
System.out.println(s);
}
可变参数(类型...args):可变参数一定要定义在参数列表最后面。
public static void show(String str,int... arr)
{
System.out.println(arr.length);
}
静态导入:当类名重名时,需要指定具体的包名。当方法重名是,指定具备所属的对象或者类。
import static java.util.Arrays.*;