------- android培训、java培训、期待与您交流! ----------
(一)Map集合
该集合存储键值对。一对一对往里存。而且要保证键的唯一性。
1.Map与Collection的区别:
Map与Collection在集合框架中属并列存在。Map存储的是键值对,Map存储元素使用put方法,而Collection使用add方法。
Map集合没有直接取出元素的方法,而是先转成Set集合,再通过迭代获取元素。Map集合中键要保证唯一性。
2.Map集合常用方法
1.添加
put(K key,V value);
putAll(Map<? extends K,?extends V> m);
//注意:put方法,如果key已经存在,则新存入的值覆盖原来的值,并把原来的值作为方法的返回值;
add方法,如果该元素已经存在,则不能存入集合,方法返回false,如果不存在,则存入集合,方法返回值为true。
2.删除
clear()
V remove(Object key)
3.判断
boolean containsKey(Object key)
boolean containsValue(Object value)
boolean isEmpty()
4.获取
V get(Object key)
int size()
Collection<V> values()
Set<Map.Entry<K,V>> entrySet()
Set<K> keySet()
3.Map体系结构
|--Hashtable:底层是哈希表数据结构,不可以存入null键,null值。该集合时线程同步的。JDK1.0,效率低。
|--HashMap:底层是哈希表数据结构。允许使用null键和null值。该集合是线程不同步的。JDK1.2,效率高。
|--TreeMap:底层是二叉树数据结构。线程不同步。可以用于该Map集合中的键进行排序。
4.Map集合与Set集合
其实Set集合底层就是使用了Map集合。
1.keySet:将Map中所有的键存入到Set集合,因为set具备迭代器。
所以可以迭代方式取出所有的键,再根据get方法获取每一个键对应的值。
Map的取出原理:将Map集合转成Set集合,再通过迭代器取出。
2.Set<Map.Entry<k,v>> entrySet():
将map集合中的映射关系存入到了Set集合中。而这个关系的数据类型就是:Map.Entry
Map.Entry 其实Entry也是一个接口,它是Map接口中的一个内部接口。
因为Entry代表关系,先有Map集合,才能有关系并且Entry代表的是Map集合中的关系。所以Entry定义在Map的内部。
代码示例(一):put方法及其返回值
import java.util.*;
class MapDemo
{
public static void main(String[] args)
{
//用泛型确定结合中对象的类型。
Map<String,String> map = new HashMap<String,String>();
//添加元素,如果出现添加时,相同的键,那么后添加的值会覆盖原有键对应值。
//并put方法会返回被覆盖的值。
System.out.println("put:"+map.put("01","zhangsan1"));
System.out.println("put:"+map.put("01","wangwu"));
map.put("02","zhangsan2");
map.put("03","zhangsan3");
System.out.println("comtainsKey:"+map.containsKey("022"));
//System.out.println("remover:"+map.remove("02"));
System.out.println("get:"+map.get("02"));
System.out.println(map);
//注意:可以通过get方法的返回值来判断一个键是否存在。通过返回null来判断。
//map.put(null,"ddddd");
//System.out.println("get:"+map.get(null));
//获取map集合中的所有的值
Collection<String> coll = map.values();
System.out.println(coll);
System.out.println(map);
}
}
代码示例(二)keySet & entrySet
/*
1.keySet():将Map中所有的键存入到Set集合,因为set具备迭代器。
所以可以迭代方式取出所有的键,再根据get方法获取每一个键对应的值。
2.entrySet();2.Set<Map.Entry<k,v>> entrySet():将map集合中的映射关系存入到了Set集合中。
而这个关系的数据类型就是:Map.Entry
*/
import java.util.*;
class MapDemo2
{
public static void main(String[] args)
{
Map<String,String> map = new HashMap<String,String>();
map.put("01","zhangsan1");
map.put("02","zhangsan2");
map.put("03","zhangsan3");
map.put("04","zhangsan4");
//1.keySet()
//先获取Map集合的所有键的Set集合,keySet();
Set<String> keySet = map.keySet();
//有了Set集合,就可以获取其迭代器
Iterator<String> it = keySet.iterator();
while (it.hasNext())
{
String key = it.next();
//有了键可以通过map集合的get方法获取其对应的值
String value = map.get(key);
System.out.println("key:"+key+",value="+value);
}
//2.entrySet()
Set<Map.Entry<String,String>> entrySet = map.entrySet();
Iterator<Map.Entry<String,String>> it1 = entrySet.iterator();
while (it1.hasNext())
{
Map.Entry<String,String> me = it1.next();
System.out.println(me.getKey()+"//"+me.getValue());
}
}
}
代码示例(三)练习
/*
练习:“advddkdkdallalafjka”获取该字符串中的字母出现的次数。
希望打印结果:a(1)(2)。。。
通过结果发现,每一个字母都有对应的次数。说明字母和次数
之间都有映射关系。
注意:当发现有映射关系时,可以选择map集合。因为map集合中
存放的就是映射关系。
什么使用map集合呢?当数据之间存在映射关系时,就要先想map集合。
思路:
1.将字符串转成字符数组,因为要对每一个字母进行操作。
2.定义一个map集合,因为打印结果的字母有顺序,所以使用TreeMap集合。
3.遍历字符数组:
将每一个字母作为键去查map集合。
如果返回null,将该字母和1存入到map集合中,
如果返回不是null,说明该字母在map集合已经存在并有对应次数。
那么就获取该次数并进行自增,然后将该字母和自增后的次数存入到TreeMap集合中
4.将TreeMap集合中的数据变成指定的字符串形式返回。
*/
import java.util.*;
class MapTest3
{
public static void main(String[] args)
{
System.out.println(charCount("aaddedkkkferedhjdhllladinn"));
}
public static String charCount(String str)
{
char[] chs = str.toCharArray();
TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();
for (int i = 0;i < chs.length ; i++ )
{
Integer value =tm.get(chs[i]);
if (value == null)
{
tm.put(chs[i],1);
}
else
{
value = value + 1;
tm.put(chs[i],value);
}
}
//定义一个容器,用于存储要输出结果及格式。
StringBuilder sb = new StringBuilder();
//定义一个Set集合,指向的是字符与数组的关系封装成的对象。
Set<Map.Entry<Character,Integer>> mapEntry = tm.entrySet();
Iterator<Map.Entry<Character,Integer>> it = mapEntry.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();
}
}
代码示例(四)TreeMap
/*
需求:对学生对象的年龄进行升序排序。
因为数据是以键值对的形式存在的,
所以要使用可以排序的Map集合:TreeMap
*/
import java.util.*;
//定义一个比较器,实现Comparator接口,重写compare方法。
class StuNameCompatator 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;
}
}
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)
{
int num = new Integer(this.age).compareTo(new Integer(s.age));
if (num == 0)
{
return this.name.compareTo(s.name);
}
return num;
}
public String getName()
{
return this.name;
}
public int getAge()
{
return this.age;
}
//将姓名和年龄封装为一个对象。
public String toString()
{
return this.name+":"+this.age;
}
}
class TreeDemo1
{
public static void main(String[] args)
{
TreeMap<Student,String> tm = new TreeMap<Student,String>(new StuNameCompatator());
tm.put(new Student("lisi1",21),"Beijing");
tm.put(new Student("lisi2",25),"tianjin");
tm.put(new Student("lisi3",23),"shanghai");
tm.put(new Student("lisi4",24),"chongqing");
tm.put(new Student("lisi3",25),"shanghai");
//定义一个Set集合,指向Student和地址的关系封装成的对象。
Set<Map.Entry<Student,String>> 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);
}
}
}
5.Map扩展知识
Map集合使用是因为具备映射关系。
代码示例:(集合嵌套)
import java.util.*;
class MapTest2
{
public static void main(String[] args)
{
//初始化一个HashMap集合,键是String类型,值是一个HashMap
HashMap<String,HashMap<String,String>> czbk = new HashMap<String,HashMap<String,String>>();
HashMap<String,String> yure = new HashMap<String,String>();
//初始化一个HashMap集合,键和值都是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","wangwu");
jiuye.put("02","wangddd");
//定义一个迭代器指向是czbk集合的键。
Iterator<String> it = czbk.keySet().iterator();
while (it.hasNext())
{
String room = it.next();
//定义一个新集合,指向czbk集合中,键对应的值(因为czbk中的值也是一个集合),
HashMap<String,String> roomMap = czbk.get(room);
//嵌套循环,小圈,定义迭代器指向新集合中的键
Iterator<String> it1 = roomMap.keySet().iterator();
while (it1.hasNext())
{
//取出键
String id =it1.next();
//取出键所对应的值。
String name = roomMap.get(id);
System.out.println(id+":"+name);
}
}
}
}
(二)Collections类:集合框架的工具类,里面定义的都是静态方法。
Collections和Collection有什么区别?
Collection
是集合框架中的一个顶层接口,它里面定义了单列集合的共性方法。
它有两个常用的子接口,
List:对元素都有定义索引。有序的。可以重复元素。
Set:不可以重复元素。无序。
Collections
是集合框架中的一个工具类。该类中的方法都是静态的
提供的方法中有可以对list集合进行排序,二分查找等方法。
通常常用的集合都是线程不安全的。因为要提高效率。
如果多线程操作这些集合时,可以通过该工具类中的同步方法,将线程不安全的集合,转换成安全的。
sort(List<T> list)
根据元素的自然顺序 对指定列表按升序进行排序。
sort(List<T> list, Comparator<? superT> c)
根据指定比较器产生的顺序对指定列表进行排序。
max(Collection<? extendsT> coll)
根据元素的自然顺序,返回给定 collection 的最大元素。
max(Collection<? extendsT> coll, Comparator<? superT> comp)
根据指定比较器产生的顺序,返回给定 collection 的最大元素。
binarySearch(List<? extends Comparable<? superT>> list, T key)
使用二分搜索法搜索指定列表,以获得指定对象。
binarySearch(List<? extendsT> list, T key, Comparator<? superT> c)
使用二分搜索法搜索指定列表,以获得指定对象。
注:要想用binarySearch必须是有序集合。
fill(List<? superT> list, T obj)
使用指定元素替换指定列表中的所有元素。
replaceAll(List<T> list,T oldVal, T newVal)
使用另一个值替换列表中出现的所有某一指定值。
reverseOrder()
返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。
reverseOrder(Comparator<T> cmp)
返回一个比较器,它强行逆转指定比较器的顺序。
synchronizedList(List<T> list)
返回指定列表支持的同步(线程安全的)列表。
代码示例:(二叉树)
/*
模拟二叉树查找字符串集合中的字符串。
*/
import java.util.*;
class CollectionsDemo2
{
public static void main(String[] args)
{
sortDemo();
}
public static void sortDemo()
{
List<String> list = new ArrayList<String>();
list.add("abcd");
list.add("ava");
list.add("tank");
list.add("fbcdd");
list.add("d");
list.add("bc");
sop(list);
//由于二叉树查找,只能查有序的集合。对集合进行自然排序。
Collections.sort(list);// 根据元素的自然顺序 对指定列表按升序进行排序。
//Collections.sort(list,new StrLenComparator());//根据指定比较器进行排序
sop(list);
int index = halfSearch(list,"d");
sop("index="+index);
int in = Collections.binarySearch(list,"d");
sop("in="+in);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
//自定义二叉树查找方法。
public static int halfSearch(List<String>list,String key)
{
int max,min,mid;
min = 0;
max = list.size() - 1;
while (min <= max)
{
mid = (max + min)>>1;// /2;
String str = list.get(mid);//获取中间的字符串对象
int num = str.compareTo(key);//调用compareTo方法比较字符串与要查找的字符串。
if(num > 0)
max = mid -1 ;
else if (num < 0)
min = mid + 1 ;
else
return mid;
}
return -1;//找不到返回-1
//return min;//要插入的位置。binarySearch返回的就是-min-1;
}
}
代码示例:(降序排列)
import java.util.*;
//自定义一个比较器,实现comparator接口。
class StrComparator implements Comparator<String>
{
public int compare(String s1,String s2)
{
return s2.compareTo(s1);
}
}
class CollectionsDemo3
{
public static void main(String[] args)
{
orderDemo();
}
public static void orderDemo()
{
//TreeSet<String> ts = new TreeSet<String>(new StrComparator());
TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder());
ts.add("avddd");
ts.add("ddd");
ts.add("vdd");
ts.add("mvddd");
Iterator<String> it = ts.iterator();
while (it.hasNext())
{
sop(it.next());
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
代码示例(练习题)
/*
练习:fill方法可以将list集合中所有元素替换成指定元素。
将list集合中部分元素替换成指定元素。
*/
import java.util.*;
class TestDemo
{
public static void main(String[] args)
{
List<String> list = new ArrayList<String>();
list.add("aaaaa");
list.add("bbbbb");
list.add("ccccc");
list.add("ddddd");
list.add("fffff");
fillDemo(list,"dd",1,2);//将list集合中部分元素替换。
//Collections.fill(list,"mm",2,3);
}
public static void fillDemo(List<String> list,String str,int start,int end)
{
//调用list中的subList方法。
List<String> sublist = list.subList(start,end);
//将sublist中全部替换为str。
Collections.fill(sublist,str);
sop(list);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
(三)Arrays:用于操作数组的工具类。
asList
(T... a)
返回一个受指定数组支持的固定大小的列表。
注意:将数组变成list集合,可以使用集合的思想和方法来操作数组中的元素,但是不可以使用集合的增删方法,因为数组的长度是固定的。
如果增删,会发生UnsupportedOperationException异常。
集合变数组: collection接口中的toArray方法。
指定类型的数组到底要定义多长呢?
当指定类型的数组长度小于集合的size,那么该方法内部会创建一个新的数组,长度为集合的size。当指定类型的数组长度大于了集合的size,就不会新创建了数组。而是 使用传递进来的数组。所以创建一个刚刚好的数组最优。
为什么要将集合变数组呢?
为了限定对元素的操作。
(四)增强for循环。
格式:
for(数据类型 变量名:被遍历的集合(Collection)或者数组)
{
}
对集合进行遍历。只能获取集合元素。但是不能对集合进行操作。迭代器除了遍历,还可以进行remove集合中元素的动作。如果使用ListIterator,还可以在遍历 过程中对集合进行增删改查的动作。
传统for循环与高级for循环的区别:高级for有一个局限性,必须有被遍历的目标。
建议在遍历数组的时候,还是希望使用传统for,因为传统for可以定义角标。代码示例:
import java.util.*;
class ForDemo
{
public static void main(String[] args)
{
//遍历ArrayList集合。
ArrayList<String> al = new ArrayList<String>();
al.add("abc1");
al.add("abc2");
al.add("abc3");
for (String s : al )
{
System.out.println(s);
}
//遍历数组
int[] arr = {1,2,3};
for(int i:arr)
{
System.out.println(i);
}
//去Map集合元素
HashMap<Integer,String> hm =new HashMap<Integer,String>();
hm.put(1,"lisi1");
hm.put(2,"lisi2");
hm.put(3,"lisi3");
//keySet方式
Set<Integer> keySet = hm.keySet();
for(Integer index : keySet)
{
System.out.println(index+"..."+hm.get(index));
}
//entrySet方式
Set<Map.Entry<Integer,String>> entrySet = hm.entrySet();
for(Map.Entry<Integer,String> me : entrySet)
{
System.out.println(me.getKey()+"::"+me.getValue());
}
}
}
(五)
JDK 1.5版本出现的新特性:
可变参数:其实就是上一种数组参数的简写形式。不用每一次都手动的建立数组对象。只要操作的元素作为参数传递即可。隐式将这些参数封装成了数组。
StaticImport:静态导入。
当类名重名是,需要指定具体的包名,当方法重名时,指定具体所属的对象或者类。
importstatic java.util.Arrays.*;//导入的是Array中所有的静态成员。代码示例:(可变参数)
class ArrDemo
{
public static void main(String[] args)
{
show(1,3,4);
}
public static void show(int... arr)//可变参数,隐式将参数封装成对象
{
System.out.println(arr.length);
System.out.print("[");
for (int i = 0; i < arr.length ; i++ )
{
System.out.print(arr[i]+",");
}
System.out.println("]");
}
}