import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/*
* Map 接口 Map中以键-值对 形式存储数据 实现类 : HashMap,Properties,HashTable
* 键 不可以重复,值可以重复
键可以为空 但是不能重复 值可以为null
* put(Object key, Object value)* get(Object key) 返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。
* remove(Object key) 如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。
* boolean containsKey(Object key) 如果此映射包含指定键的映射关系,则返回 true。
boolean containsValue(Object value) 如果此映射将一个或多个键映射到指定值,则返回 true。
int size() 返回此映射中的键-值映射关系数。
* Collection<V> values() 返回此映射中包含的值的 Collection 视图。
* Set keySet() 返回此映射中包含的键的 Set 视图。
* Set entrySet() 返回此映射中包含的映射关系(key-value)的 Set 视图。
*
* boolean isEmpty() 如果此映射未包含键-值映射关系,则返回 true。
*/
public class Test08Map {
public static void main(String[] args) {
// TODO Auto-generated method stub
Map map=new HashMap();
System.out.println("map 集合是否为空:"+map.isEmpty());
map.put("lucy", 12522252552l);
map.put("ja",null);
map.put("10001", new Person("Tom",20));
map.put("10002", new Person("Tom",20));
map.put("10002", new Person("jack",21));
map.put(1, "张三");
System.out.println("map 集合是否为空:"+map.isEmpty());
//key-value 个数
System.out.println("键值对个数 :"+map.size());
System.out.println(map.get(1));
System.out.println(map.get("lucy"));
System.out.println(map.get("10001"));
System.out.println(map.get(2)); //不包含该键的映射关系,则返回 null
System.out.println("map集合是否包含10001的key:"+map.containsKey("10001"));
System.out.println("map集合是否包含10002的key:"+map.containsKey("10002"));
System.out.println("map集合是否包含张三的value:"+map.containsValue("张三"));
System.out.println("map集合是否包含Tom的value:"+map.containsValue(new Person("Tom",20)));
//对Map的value进行遍历
Collection cl1=map.values();
Iterator it=cl1.iterator();
while(it.hasNext()){
System.out.println("map 的Value集合元素 :"+it.next());
}
//对Map的Key进行遍历
Set set=map.keySet();
Iterator it2=set.iterator();
while(it2.hasNext()){
System.out.println("map 的key集合元素 :"+it2.next());
}
/* //把名字叫"张三"的人删除掉
Set deleteZhangsan=map.keySet();
Iterator itTemp=deleteZhangsan.iterator();
while(itTemp.hasNext()){
Object key=itTemp.next();
//根据key 获取value 判断value值是否是"张三"
if(map.get(key).equals("张三")){
//删除"张三"对应的key
// map.remove(key);
// return
}
}*/
//堆map 的key-value 进行迭代
Set setKeyValue=map.entrySet();
Iterator it3=setKeyValue.iterator();
while(it3.hasNext()){
Entry<String, Object> entry2 = (Entry<String, Object>) it3.next();
System.out.println(entry2.getKey()+":"+entry2.getValue());
System.out.println("map 的key-value映射:"+it3.next());
}
}
}
**
* 输入一串字符串,判断每个字符的个数;
* abdfdfsa a(2)b(1)d(2)f(2)s(1)
*分析:将字符串转换成数组;
*将字符数组中的元素放到map集合中(利用put(k,v)返回值是value)
* 元素作为集合的key,出现的次数作key
* 1. 将字符放到key中,看返回值
* 返回值不是null 说明有该字符则将该key对应的value++;
* 返回值是null 说明不存在这个key
* 2.遍历整个treemap集合将键 值添加到stringbuffer中
Scanner sc = new Scanner(System.in);
System.out.println("请输入一串字符");
String str = sc.nextLine();
char [] ch = str.toCharArray();
TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();
for(char ch1:ch){
Integer i = tm.put(ch1, 1);
if(i!=null) tm.put(ch1, i+1);
}
StringBuffer sb = new StringBuffer();
Set<Entry<Character, Integer>> entry= tm.entrySet();
for(Entry<Character, Integer> e:entry)
{
sb.append(e.getKey()).append("(").append(e.getValue()).append(")");
}
System.out.println(sb.toString());
java 集合(list、set、map)的特点
集合相关的类有一大堆,一般也只用到常用的方法增删改查,而且它它们的方法名也基本一样,所以一直都不知道什么时候用什么集合,
今天趁有空特意从网上整理资料方便日后回忆。
一、List:、有顺序以线性方式存储,可以存放重复对象
线程安全方法:List list = Collections.synchronizedList(new LinkedList(...));
LinkedList:双向链表实现存储 索引数据慢插入数度较快 线程不安全(比安全性能好)
ArrayList:数组方式存储数据 索引数据快插入数据慢 线程不安全
Vector:数组方式存储数据 索引数据快插入数据慢 线程安全
Stack:继承自Vector,实现一个后进先出的堆栈
二、Set:无顺序,不包含重复的元素
HashSet:为快速查找设计的Set。存入HashSet的对象必须定义hashCode()。
TreeSet: 保存次序的Set, 底层为树结构。使用它可以从Set中提取有序的序列。
LinkedHashSet:具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的次序)。于是在使用迭代器遍历Set时,结果会按元素插入的次序显示。
三、Map:键必须是唯一
同步方法:Map m = Collections.synchronizedMap(new TreeMap(...));
Hashtable:基于散列表的实现 允许空键空值 线程安全
HashMap:基于散列表的实现 允许空键空值 线程不安全 (与Hashtable基本一致)
TreeMap: 基于红黑树数据结构的实现 不允许空键空值 线程不安全
WeakHashMap:改进的HashMap,它对key实行“弱引用”,如果一个key不再被外部所引用,那么该key可以被GC回收。
在除需要排序时使用TreeSet,TreeMap外,都应使用HashSet,HashMap,因为他们的效率更高。
ConcurrentModificationException异常根本原因
以上都有3种出现异常的情况有一个共同的特点,都是使用Iterator进行遍历,且都是通过ArrayList.remove(Object) 进行删除操作。
想要找出根本原因,直接查看ArrayList源码看为什么出现异常:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
|
List、Set、Map 都可以通过Iterator进行遍历,这里仅仅是通过List举例,在使用其他集合遍历时进行增删操作都需要留意是否会触发ConcurrentModificationException异常。
3.解决方案
map.remove() 改:iterator.remove()
使用Iterator遍历集合时,不要改动被迭代的对象,可以使用 Iterator 本身的方法remove() 来删除对象, Iterator.remove() 方法会在删除当前迭代对象的同时维护modCount和expectedModCount值的一致性。