Map集合:Map(k,v)该集合存储键值对,一对一对往里存,而且要保证键的唯一性。
1.添加:
put(K key,V value)
putAll(Map<? extends K,?extends V> m)
2.删除:
clear();
remove();
3.判断:
containsValue(Object value)
containsKey(Object key)
isEmpty()
4.获取:
get(Object key)
size()
values()
重点:Map集合的两种取出方式:
1.Set<k>keySet():将map中所有的键存入到Set集合中,因为Set具备迭代器,再根据get方法,获取每一个键对应的值。
Map集合的取出原理:将map集合装成set集合,再通过迭代器取出。
2.Set<Map.Entry<k,v>> entrySet():
注解:Map.Entry 其实Entry是一个接口,它是Map接口中的一个内部接口。
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#333333;">interface Map { public static interface Entry { public abstract Object getKey(); public abstract Object getValues(); } } class HashMap implements Map { class Hashs implements Map.Entry { public Object getKey(){}; public Object getValue(){}; } } </span>
Map
|--Hashtable:底层是哈希表结构,不可以存入null键null值,该集合是同步的。JDK 1.0 效率低
|--HashMap:底层是哈希表数据结构,并允许使用null键null值,该集合不同步。JDK 1.2 效率高
|--TreeMap:底层是二叉树数据结构,线程不同步,可以用于个map集合中的键进行排序。
和Set很像。
其实Set此层就是使用了Map集合。
*/
/*Map共性方法*/
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#333333;">import java.util.*; class MapDemo { public static void main(String[] args) { Map<String,String>map=new HashMap<String,String>(); //添加元素 map.put("01","zhangsan1"); System.out.println(map.put("01","wangwu"));//添加元素时,如果出现添加相同的键,那么后添加的值会覆盖原有键对应的值。 //并put方法会返回被覆盖的值。 map.put("03","zhangsan3"); System.out.println("containsKey:"+map.containsKey("022")); //System.out.println("remove:"+map.remove("02")); map.put("04",null) System.out.println("get:"+map.get("04")); //可以通过get方法的返回值来判断一个键是否存在。通过返回空来判断。 //获取map集合中所值有的 Collection <String> coll=map.values();//valuse()方法返回Collection集合类型值,该集合要指定泛型。 System.out.println(coll); System.out.println(map); } } </span>
//keySet()方法:
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#333333;">import java.util.*; class MapDemo2 { public static void main(String[] args) { Map<String,String> map=new HashMap<String,String>(); map.put("02","zhangsan2"); map.put("03","zhangsan3"); map.put("01","zhangsan1"); map.put("04","zhangsan4"); //将Map集合中的映射关系取出,存入到Set集合中。 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();//Map.Entry<>类,可理解为关系,有getKey(),getvalue()方法。 String key=me.getKey(); String value=me.getValue(); System.out.println(key+":"+value); } /* //获取map集合的所有键的Set集合,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:"+key); //有了键,就可以通过map集合的get方法获取其对应的值 System.out.println("key:"+key+",value"+value); } */ } }</span>
/*每一个学生都有相应的归属地。
学生Student,地址String
学生属性:姓名,年龄。
注意:姓名和年龄相同的学生视为同一个学生。
保证学生唯一性。
1.描述学生。
2.定义map容器,将学生作为键,地址作为值,存入。
3.获取map集合中的元素。
*/
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#333333;">import java.util.*; class Student implements Comparable<Student> { private String name; private int age; Student(String name,int age) { this.name=name; this.age=age; } public int compareTo(Student s)//复写compareTo()方法,实现Comparable是因为,学生类可能储存到TreeSet中。 { int num=new Integer(this.age).compareTo(new Integer(s.age));//将年龄封箱成Integer类,使其调用compareTo方法,进行比较 if(num==0) return this.name.compareTo(s.name); return num; } public int hashCode()//复写hashCode(),equals(),是因为学生有可能储存到hashSet中。 { 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("lisi1",21),"tianjin"); hm.put(new Student("lisi3",23),"nanjing"); hm.put(new Student("lisi4",24),"wuhan"); //第一种取出方式 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(stu+"..."+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+"........"+addr); } } } </span>
/*需求:对学生对象的姓名进行升序排序
因为数据是以键值对形式存在的。所以要使用可以排序的Map集合,TreeMap
另外:因为Student类中compareTo方法已经固定,故使用比较器Comparator。
*/
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#333333;">import java.util.*; class StuNameComparator implements Comparator<Student> { public int cmopare(Student s1,Student s2) { int num=s1.getName().compareTo(s2.getName()); if(num==0) return new Integer(s1.getAge()).compareTo(new Integer(s2.get.Age())); return num; } } class MapTest2 { public static void main(String[] args) { TreeMap<Student,String> tm=new TreeMap<Student,String>(new StuNameComparator()); tm.put(new Student("blisi3",23),"nanjing"); tm.put(new Student("lisi1",21),"beijing"); tm.put(new Student("1lisi4",24),"wuhan"); tm.put(new Student("blisi2",22),"shanghai"); Set<Student> entrySet =tm.entrySet(); Iterator<Map.Entry<Student,String>> it=entrySet.iterator(); while(it.hasNext()) { Map.Entry<Student,String >me =it.next(); Student stu=me.getKey(); String addr=me.getValue(); System.out.println(stu+"..."+addr); } } } </span>
/*练习:
“addfagjgajghe”获取该字符串中的字母出现的次数。
希望打印结果: a(1)c(2)...
通过结果发现,每一个字母都有对应的次数。
说明字母和次数之间都有映射关系。
注意:当发现有映射关系时,可以选择map集合。
因为map集合中存放就是映射关系。
什么时候使用map集合呢??
当数据之间存在映射关系时,就要先想map集合。
思路:
1.将字符串转换成字符数组,因为要对每一个字母进行操作。
2.定义一个map集合,因为打印结果的字母有顺序,所以使用treemap集合。
3.遍历字符数组。
将每一个字母作为键去查map集合。
如果返回null,将该字母和1存入到map集合中。
如果返回不是null,说明该字母在map集合已经存在,并有对应次数。
那么就获取该次数并进行自增,然后将该字母和自增后的次数存入到map集合中--覆盖掉原来键对应的值。
4.将map集合中的数据变成指定的字符串形式返回
*/
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#333333;">import java.util.*; class MapTest3 { public static void main(String[] args) { String s=charCount("aabfcdabcdefa"); System.out.println(s); } public static String charCount(String str) { char[] chs=str.toCharArray(); TreeMap<Character,Integer> tm=new TreeMap<Character,Integer>(); //!!!泛型类中接受的都是引用数据类型,所以必须转换成对应的包装类 for(int x=0;x<chs.length;x++) { if(!(chs[x]>='a' && chs[x]<='z'||chs[x]>='A' && chs[x]<='Z')) continue;//如果不是字母,继续循环。 Integer value=tm.get(chs[x]); if(value==null) { tm.put(chs[x],1); } else { value=value+1; tm.put(chs[x],value); } } //System.out.println(tm); //return null; StringBuilder sb=new StringBuilder(); 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(); } } </span>
/*map扩展知识。
map集合被使用是因为具备映射关系。
一个学校有多个教室,每一个教室都有名称。
*/
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#333333;">import java.util.*; class Student { private String id; private String name; Student(String id,String name) { this.id=id; this.name=name; } public String toString() { return id+":::"+name; } } class MapDemo3 { public static void demo() { HashMap<String,List<Student>> czbk=new HashMap<String,List<Student>>(); List<Student> reyu=new ArrayList<Student>(); List<Student> jiuye=new ArrayList<Student>(); czbk.put("yureban",reyu); czbk.put("jiuyeban",jiuye); reyu.add(new Student("01","zhangsan")); reyu.add(new Student("04","wangwu")); jiuye.add(new Student("01","zhouqi")); jiuye.add(new Student("02","zhaoli")); Iterator<String> it=czbk.keySet().iterator(); while(it.hasNext()) { String roomName=it.next(); List<Student> room=czbk.get(roomName); System.out.println(roomName); getInfos(room); } } public static void getInfos(List<Student> list) { Iterator<Student> it=list.iterator(); while(it.hasNext()) { Student s=it.next(); System.out.println(s); } } public static void main(String[] args) { demo(); } }</span>
集合框架的工具类Collections
sort():
public static <T extends Comparable<? super T>>void sort(List<T> list)
{}
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#333333;">import java.util.*; class CollectionsDemo { public static void main(String[] args) { /* sortDemo(); maxDemo(); binarySearchDemo(); fillDemo(); //binarySearchDemo */ replaceAllDemo(); } public static void sortDemo()//对list进行排序 { List<String> list=new ArrayList<String>(); list.add("abcd"); list.add("aaa"); list.add("kkkkk"); list.add("qq"); sop(list); Collections.sort(list/*,new StrLen_Comparator()*/);//Collections工具类的排序方法。可用比较器 sop(list); } public static void maxDemo()//list中的最大值 { List<String> list=new ArrayList<String>(); list.add("abcd"); list.add("aaa"); list.add("kkkkk"); list.add("qq"); sop(list); String max=Collections.max(list/*,new StrLen_Comparator()*/); sop("max="+max); } public static void binarySearchDemo()//对某元素进行二分查找 { List<String> list=new ArrayList<String>(); list.add("abcd"); list.add("aaa"); list.add("kkkkk"); list.add("qq"); sop(list); int index=Collections.binarySearch(list,"aaa",new StrLen_Comparator()); //返回负数,说明不存在。可用比较器 sop("index="+index); } public static void shuffleDemo()//对集合中元素进行随机打乱。 { List<String> list=new ArrayList<String>(); list.add("abcd"); list.add("aaa"); list.add("kkkkk"); list.add("qq"); sop(list); Collections.shuffle(list); sop(list); } public static void fillDemo() { List<String> list=new ArrayList<String>(); list.add("abcd"); list.add("aaa"); list.add("kkkkk"); list.add("qq"); sop(list); Collections.fill(list,"p");//集合中元素替换成指定元素。 sop(list); } /*练习:fill方法可以将list集合中所有的元素替换成指定元素。怎么将list集合中部分元素替换成指定元素呢?*/ public static void replaceAllDemo() { List<String> list=new ArrayList<String>(); list.add("abcd"); list.add("aaa"); list.add("kkkkk"); list.add("qq"); sop(list); Collections.replaceAll(list,"aaa","ppp"); sop(list); Collections.reverse(list); sop(list); } public static void sop(Object obj) { System.out.println(obj); } } class StrLen_Comparator implements Comparator<String>//当 对Collections工具类中的默认排序方法不满意时, //可以定义自己的排序方法,只要实现比较器Comparator接口,重写comapre方法即可。 { public int compare(String s1,String s2) { if(s1.length()>s2.length()) return 1; if(s1.length()<s2.length()) return -1; return s1.compareTo(s2);//当两字符相等时,进行默认的字典比较。 } } </span>
/*Collections-reverseOrder()*/
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#333333;">import java.util.*; class CollectonsDemo2 { public static void main(String[] args) { orderDemo(); } public static void orderDemo() { TreeSet<String> ts=new TreeSet<String>(Collections.reverseOrder());//Collectons.reverseOrder()方法,可将系统默认的比较方法产生的自然顺序反转。 /// TreeSet<String> ts=new TreeSet<String>(Collections.reverseOrder(new StrComparator()));//Collectons.reverseOrder(比较器)方法,可以将现有的比较器产生的顺序,强行反转。 ts.add("abcde"); ts.add("aaa"); ts.add("k"); ts.add("cccccc"); Iterator it=ts.iterator(); while(it.hasNext()) { System.out.println(it.next()); } } }</span>
/*集合工具类:Arrays
用于操作数组的工具类,里面都是静态方法。
*/
/*asList:将数组变成list集合。 */
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#333333;">import java.util.*; class ArraysDemo { public static void main(String[] args) { // int[] arr={2,4,5}; // System.out.println(Arrays.toString(arr));//原来数组变字符串方法。 String[] arr={"abc","cc","kkk"}; //把数组变成list集合有什么好处??? /*可以使用集合的思想和方法来操作数组中的元素。 注意:将数组变成集合,不可以使用集合的增删方法,因为数组的长度时固定的。 可用contains,get,indexOf(),subList()等等方法。 如果增删,那么会发生UnsupportedOperationExc。 */ List<String> list=Arrays.asList(arr);//将数组变成集合 sop("contains:"+list.contains("cc")); //list.add("qq");//UnsupportedOperatorExc sop(list); int[] nums={2,3,5}; List li=Arrays.asList(nums); sop(li);//输出结果为数组的地址,而不是数组中元素。 /*如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在 如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接转成集合中的元素。 所以可写成以下形式: */ Integer[] nums2={2,4,5}; List<Integer>li2=Arrays.asList(nums2); sop(li2); } public static void sop(Object obj) { System.out.pritln(obj); } } </span>
/*集合转成数组
Collection接口中的toArray方法。
*/
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#333333;">import java.util.*; class CollectionToArray { public static void main(String[] args) { ArrayList<String> al=new ArrayList<String>(); al.add("abc1"); al.add("abc2"); al.add("abc3"); /* 1.指定类型的数组到底要定义多长呢? 当指定类型的数组长度小于集合的size,那么该方法内部会创建一个新的数组,长度为集合的size。 当指定类型的数组长度大于集合的size,就不会新创建数组,而是使用传递进来的数组。 所以创建一个刚刚好的数组最优。 2.为什么要将集合变数组。 为了限定对元素的操作。不需要进行增删了。 */ String[] arr=al.toArray(new String[al.size()]);//new String[al.size()]:创建存储该集合元素的数组,并指定大小。 System.out.println(Arrays.toString(arr)); } } </span>
/*增强for循环
格式:
for(数据类型 变量名:被遍历的集合(Collection)或者数组)
{
}
对集合进行遍历,只能获取集合元素,但是不能对集合进行操作。
迭代器 除了遍历,还可以进行remove集合中元素的动作。
如果使用ListIterator,还可以在遍历过程中对集合进行增删改查 操作。
传统for和高级for有什么区别呢??
高级for有一个局限性,必须有被遍历的目标。
建议在遍历数组时,还是希望用传统for,因为传统for可以定义角标。
*/
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#333333;"> import java.util.*; class ForEachDemo { public static void main(String[] args) { ArrayList<String> al=new ArrayList<String>(); al.add("abc1"); al.add("abc2"); al.add("abc3"); /* JDK1.2-1.4都是用迭代器 Iterator<String> it=al.iterator(); while(it.hasNext()) { System.out.println(it.next()); } */ /*JDK1.5以后用高级for循环*/ for(String s:al) { System.out.println(s); } int[] arr={3,5,1}; for(int i:arr) { System.out.println(i); } HashMap<Integer,String> hm=new HashMap<Integer,String>(); hm.put(1,"a"); hm.put(2,"b"); hm.put(3,"c"); Set<Integer> keySet=hm.keySet();//将键值存入Set集合 for(Integer i:keySet) { System.out.println(i+"::"+hm.get(i)); } //Set<Map.Entry<Integer,String>> entrySet=hm.entrySet(); //for(Map.Entry<Integer,String>) me:entrySet)相当于以下语句: for(Map.Entry<Integer,String> me : hm.entrySet()) { System.out.println(me.getKey()+"---"+me.getValue()); } } } </span>
/*可变参数
JDK1.5版出现的新特性。
方法的可变参数。
在使用时注意:
!!可变参数一定要定义参数数列表最后面。
*/
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#333333;">class ParamMethodDemo { public static void main(String[] args) { /*每次定义一个数组,作为实际参数 int[]arr={3,4}; show(arr); int[] arr1={3,5,6,6}; show(arr1);*/ /* 可变参数: 其实就是上一中数组参数的简写形式。 不用每一次都手动的建立数组对象。 只要将要操作的元素作为参数传递即可。 隐式将这些参数封装成了数组。 */ show("hahahah",2,3,5,6);//可变参数会把2,3,5,6隐式封装成数组 } public static void show(String str,int....arr)//...为可变参数,int...arr为数组 { System.out.println(arr.length); } }</span>
/*StaticImport 静态导入
当类名重名时,需要指定具体的包名。
当方法重名时,指定具备所属的对象或则类。
*/
<span style="font-family:KaiTi_GB2312;font-size:18px;color:#333333;">import java.util.*; import static java.util.Arrays.*://“static”,导入的是Arrays这个类中的所有静态成员。 import static java.lang.System.*;//导入了System类中所有静态成员。 class StaticImport { public static void main(String[] args) { int[] arr={3,1,5}; //Arrays.sort(arr);Arrays可省略,写成sort(arr) sort(arr); int index=binarySearch(arr,1); out.println(Arrays.toString(arr));//此处省去System. ,另外toString()前的Arrays不可省,因为本类是继承Object类,Object中也有此方法 .out.println("Index="+index); } }</span>