map

package com.yh.container;

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

publicclassArrayList<e>extendsAbstractList<e>

        implementsCloneable, Serializable, RandomAccess {

         

         

         @Overridepublicbooleanremove(Object object) {

        Object[] a = array;

        ints = size;

        if(object !=null) {

            for(inti = 0; i < s; i++) {

                if(object.equals(a[i])) {

                    System.arraycopy(a, i +1, a, i, --s - i);

                    a[s] =null// Prevent memory leak

                    size = s;

                    modCount++; // 只要删除成功都是累加

                    returntrue;

                }

            }

        }else{

            for(inti = 0; i < s; i++) {

                if(a[i] ==null) {

                    System.arraycopy(a, i +1, a, i, --s - i);

                    a[s] =null// Prevent memory leak

                    size = s;

                    modCount++; // 只要删除成功都是累加

                    returntrue;

                }

            }

        }

        returnfalse;

    }  

 

 

    @OverridepublicIterator<e> iterator() {

        returnnewArrayListIterator();

    }  

         

    privateclassArrayListIteratorimplementsIterator<e> {

          ......

    

          //全局修改总数保存到当前类中

        /** The expected modCount value */

        privateintexpectedModCount = modCount;

 

        @SuppressWarnings("unchecked")publicE next() {

            ArrayList<e> ourList = ArrayList.this;

            intrem = remaining;

               //如果创建时的值不相同,抛出异常

            if(ourList.modCount != expectedModCount) {

                thrownewConcurrentModificationException();

            }

            if(rem ==0) {

                thrownewNoSuchElementException();

            }

            remaining = rem -1;

            return(E) ourList.array[removalIndex = ourList.size - rem];

        }  

         

          ......

     }

}   </e></e></e></e></e>


List
、Set、Map 都可以通过Iterator进行遍历,这里仅仅是通过List举例,在使用其他集合遍历时进行增删操作都需要留意是否会触发ConcurrentModificationException异常。

3.解决方案

map.remove() 改:iterator.remove()

 

使用Iterator遍历集合时,不要改动被迭代的对象,可以使用 Iterator 本身的方法remove() 来删除对象, Iterator.remove() 方法会在删除当前迭代对象的同时维护modCount和expectedModCount值的一致性。

 

 

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值