------- android培训、java培训、期待与您交流! ----------
黑马程序员——集合框架(双列集合:Map接口)
Map:
Map:该集合存储键值对,一对一对往里存,而且要保证键的唯一性。
|----Hashtable:底层是哈希表数据结构,不可以存入null键null值。
该集合是线程同步的。Jdk1.0效率低
|----Properties:和HashMap相似,在实际应用中非常重要,主要用来存储字符串
类型的键和值。
|----HashMap:底层是哈希表数据结构,允许使用null键null值。
线程不同步。Jdk1.2效率高
|----TreeMap:底层是二叉树数据结构,线程不同步,可以用于给Map集合中的键值
进行排序,和Set很像,其实Set底层就是使用了Map集合
Map集合的常用方法:
-
添加
put(K key, V value)
putAll(Map<? extends K,? extends V> m)
-
删除
clear()
remove(Obiect value)
-
判断
containsValue(Objectvalue)
containsKey(Object key)
isEmpty()
-
获取
get(Object key)
size()
values()
keyset()
entrySet()
Map方法演示:
import java.util.*;
class MapDemo
{
publicstatic void main(String[] args)
{
Map<String,String>map = new HashMap<String,String>();
//添加元素
map.put("01","zhangsan1");
map.put("02","zhangsan2");
//添加元素时,如果出现同一个键,那么后添加的值会将原来的覆盖,put方法会返回原来的值,如果此键原来没有值,则返回null
sop("put:"+map.put("03","zhangsan3"));
sop("put:"+map.put("03","wangwu"));
sop("containsKey:"+map.containsKey("02"));//通过键值查看是否有对应的值
sop("remove:"+map.remove("02"));//通过键值,获取并删除该键所对应的值
sop("get:"+map.get("02"));//获取该键所对应的值
map.put(null,"haha");//HashMap集合null是可以作为键存在的。也可以作为值存在
sop("get:"+map.get(null));//可以通过get方法的返回值来判断一个键是否存在,通过返回null来判断
Collection<String> coll = map.values();//获取map集合中所有的值,返回值类型是Collection集合。
sop(coll);
sop(map);//打印集合
}
publicstatic void sop(Object obj)
{
System.out.println(obj);
}
}
Map集合的两种取出方式:
Map集合的取出原理,将map集合转成set集合,再通过迭代器取出
1,Set<K>keySet:将map中所有的键存入到Set集合,因为Set具备迭代器所有可以迭代方式取出的键,在根据get方法,获取每一个键对应的值。
2,Set<Map.Entry<K,V>>entrySet:将map集合中的映射关系存入到了set集合中,而这个关系的数据类型就是:Map.Entry
演示代码:
import java.util.*;
class MapDemo2
{
publicstatic void main(String[] args)
{
Map<String,String>map = new HashMap<String,String>();
map.put("02","zhang2");
map.put("04","zhang4");
map.put("01","zhang1");
map.put("03","zhang3");
//将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<K,V>是一个接口,getKey()和getValue()是接口中的方法
Stringkey = me.getKey();
Stringvalue = me.getValue();
System.out.println("key:"+key+",value:"+value);
}
//keySet:
/*
//先获取map集合的所有键的Set集合,keySet();
Set<String>keySet = map.keySet();
//有了Set集合,就可以使用迭代器取出
Iterator<String>it = keySet.iterator();
while(it.hasNext())
{
Stringkey = it.next();
//有了键就可以通过map集合的get方法获取其对应的值。
String value = map.get(key);
System.out.println("key:"+key+",value:"+value);
}
*/
}
}
/*
Map.Entry :其实Entry也是一个接口,它是Map接口中的一个内部接口
interface Map
{
publicstatic interface Entry
{
publicabstract Object getKey();
publicabstract Object getValue();
}
}
class HashMap implements Map
{
classHash implements Map.Entry
{
publicObject getKey(){}
publicObject getValue(){}
}
}
*/
练习:
"sdfgzxcvasdfxcvdf"获取该字符串中的字母出现次数。
希望打印结果:a(1)c(2)......
通过结果发现,每一个字母都有对应的次数。
说明字母和次数之间都有映射关系。
注意了,当发现有映射关系时,可以选择map集合。
因为map中存放的就是映射关系。
什么时候使用map呢?
思路:
1,将每一个字符串转换成字符数组,因为要对每一个字母进行操作
2,定义一个map集合,因为打印结果的字母有顺序,所以使用treemap集合
3,遍历字符数组
将每一个字母作为键去查map集合
如果返回null,将该字母和1存入到map集合中
如果返回的不是null,说明该字母在map集合已经存在并有对应次数
那么就获取该次数并进行自增,然后将该字母和自增后的次数存入到map集合中,覆盖原键所对应的值
4,将map集合中的数据变成指定的字符串形式返回。
*/
import java.util.*;
class MapTest3
{
publicstatic void main(String[] args)
{
Strings = charCount("abcab/,cde-=abcd+<?efj");
System.out.println(s);
}
publicstatic String charCount(String str)
{
char[]chs = str.toCharArray();//将字符串转换成字符数组
TreeMap<Character,Integer>tm = new TreeMap<Character,Integer>();//定义一个容器,字母作为键,次数作为值
intcount = 0;
for(intx=0; x<chs.length; x++)//遍历数组
{
if(!(chs[x]>='a'&& chs[x]<='z' || chs[x]>='A' && chs[x]<='Z'))
continue;
Integervalue = tm.get(chs[x]);//通过键查找对应的值
if(value!=null)
count= value;
count++;
tm.put(chs[x],count);
count= 0;
/*
if(value==null)
{
tm.put(chs[x],1);
}
else
{
value= value + 1;
tm.put(chs[x],value);
}
*/
}
//System.out.println(tm);
//定义缓冲区
StringBuildersb = 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();
Characterkey = me.getKey();
Integervalue = me.getValue();
sb.append(key+"("+value+")");//已打印形式存入缓冲区
}
returnsb.toString();
}
}
Properties:
/*
Properties是hashtable的子类
也就是说它具备map集合的特点,而且它里面存储的键值对都是字符串
是集合中和IO技术相结合的集合容器
该对象的特点:可以用于键值对形式的配置文件
那么在加载数据时,需要数据具有一定的格式:键=值
*/
import java.util.*;
import java.io.*;
class PropertiesDemo
{
public staticvoid main(String[] args) throws IOException
{
loadDemo();
}
//Properties集合中的load方法可以直接从流中获取数据,下面的方法(method_1();),是load方法的内部实现原理
public staticvoid loadDemo()throws IOException
{
Propertiesprop = new Properties();
FileInputStreamfis = new FileInputStream("info.txt");
//将流中的数据加载进集合
prop.load(fis);//只需这一个方法即可实现下面方法的功能,load方法可以加载字节流,字符流(JDK1.6出现)
//System.out.println(prop);
//想要改变文件中值
prop.setProperty("wangwu","39");
//写一个输出流,因为重新设置的值要从集合中写入文件
FileOutputStreamfos = new FileOutputStream("info.txt");
//参数haha是备注,在文件中显示在#号后面,不会被Properties解释执行
prop.store(fos,"haha");//此方法可以将集合中的数据写入到流中
prop.list(System.out);//list方法,参数是打印流,可以列出集合中的元素
}
/*
演示,如何将流中的数据存储到集合中
需求:想要将info.txt中键值数据存到集合中进行操作
思路:1,用一个流和info.txt文件关联
2,读取一行数据,将该行数据用"="进行切割
3,等号左边作为键,右边作为值,存入到Properties集合中即可
*/
publicstatic void method_1()throws IOException
{
BufferedReaderbr = new BufferedReader(new FileReader("info.txt"));
Stringline = null;
Properties prop= new Properties();
while((line=br.readLine())!=null)
{
//System.out.println(line);//验证是否取到文件中值
String[]arr = line.split("=");//用字符串切割方法,将建和值切割,存入数组
//System.out.println(arr[0]+":"+arr[1]);//验证切割后的值是否存入数组
prop.setProperty(arr[0],arr[1]);//将数组中取到的键和值存入集合
}
System.out.println(prop);//验证是否将文件数据存到了集合中
}
//设置和获取元素
publicstatic void setAndGet()
{
Propertiesprop = new Properties();//创建Properties集合
prop.setProperty("zhangsan","30");//设置元素,也就是此集合的添加方法,都是字符串
prop.setProperty("lisi","50");
//修改lisi的年龄
prop.setProperty("lisi","80");//键相同会覆盖原来的值,可用于修改值
//System.out.println(prop);//打印集合
Stringvalue = prop.getProperty("lisi");//获取元素,通过键,获取其值
System.out.println(value);
Set<String>names = prop.stringPropertyNames();//遍历集合,返回一个set集合(获取的是键)
for(Strings : names)
{
System.out.println(s+":"+prop.getProperty(s));
}
}
}