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>