JAVA集合

JAVA集合,第1张

一、Map接口继承树

1、Map实现类的一些特点

  • Map接口:双列数据,存储key-value对的额数据 --类似于高中的函数:y=f(x)。
    • HashMap:作为Map的主要实现类;线程不安全,效率高;存储null的key和value
      • LinkedHashMap:保证在遍历map元素时,可以按照添加的顺序实现遍历。
      • 原因:在原有的HashMap底层结构基础上,添加了一对指针,指向前一个和后一个数据 多与频繁的遍历 *** 作,此类执行效率高于HashMap
    • TreeMap:保证按照添加的key-value 对进行排序,实现排序遍历。此时考虑key的自然排序或定制排序。底层使用红黑树
    • Hashtable:作为古老的实现类;线程不安全,效率低;不能存储null的key和value。
      • Properties:常用来处理配置文件。key和value都是String类型
二、Map结构的理解

Map中的key:无序的、不可重复的,使用set存储所有的key —》key所在的类要重写equals()和hashCode() .(以HashMap为例)

Map中的value:无序的、可重复的,使用Collection存储所有的value—》value所在的类要重写equals()。

一个键值对:key-value构成了一个Entry对象。

Map中的entry:无序的、不可重复的,使用Set存储所有的entry。

//存储null的key和value举例
    @Test
    public void test1(){
         Map map = new HashMap();
         //map= new Hashtable();会报错NullPointerException指针异常
         map.put(null,123);
    }
三、HashMap的底层实现原理(以jdk7为例说明)

HashMap map=new HashMap();

在实例化以后,底层创建了长度16的一维数组Entry[] table。

…可能已经执行过多次put…

map.put(key1,value1);

  • 首先,请用key1所在类的hashCode()计算key1哈希值,此哈希值经过某种算法计算以后,得到Entry数组中的存放位置。
    • 如果此位置上的数据为空,此时key1-value1添加成功。–》情况1
    • 如果此位置上的数据不为空,(意味着此位置存在一个或多个数据(以链表的形式存在)),比较key1和已经存在的一个或多个数据的哈希值:
      • 如果key1的哈希值与已经存在的数据的哈希值都不相同,此时key1-value1添加成功。—》情况2
      • 如果key1的哈希值和已经存在的某个数据(key2-value2)的哈希值相同,继续比较:调用key1所在类的equals(key2):
        • 如果equals()返回false:此时key1-value1添加成功。–》情况3
        • 如果equals()返回true:使用value1替换相同key的value值。

补充:关于情况2和情况3:此时key1-value1和原来的数据以链表的方式存储。

在不断的添加工程中,会涉及到扩容问题,默认的扩容方式:扩容为原来容量的2倍,并将原有数据复制过来。

jdk8相较于jdk7底层实现的不同:

​ 1、new HashMap():底层没有创建一个长度为16的数组

​ 2、jdk8底层的数组是:Node[],而非Entry[]




四、LinkedHashMap的底层实现原理(了解)

内部类Entry能够记录添加的元素的先后顺序。

五、Map常用方法

1、添加、删除、修改 *** 作举例:

  @Test
    public void test3(){
        Map map = new HashMap();

        //添加 *** 作
        map.put("AA",123);
        map.put(45,123);
        map.put("BB",56);
        //修改(与原有的相同会替换原有的vlaue)
        map.put("AA",16);
        System.out.println(map);

        Map map1 = new HashMap();
        map1.put("CC",123);
        map1.put("DD",123);
        //将map1中所有的key-vauel值全部放到当前map中
        map.putAll(map1);
        System.out.println(map);
        
        //remove(Object key);key不存在返回的是null
        Object value = map.remove("CC");
        System.out.println(value);
        System.out.println(map);

        //clear()
        map.clear();//清除数据,map还存在
        System.out.println(map.size());
        System.out.println(map);
    }

2、元素查询的 *** 作举例:

 @Test
    public void test4(){
        Map map = new HashMap();
        map.put("AA",123);
        map.put(45,123);
        map.put("BB",56);

        //Object get(Object key)获取对应的value
        System.out.println(map.get(45));

        //containsKey(Object key)是否包含指定的key
        boolean isExist = map.containsKey("BB");
        System.out.println(isExist);

        //containsValue(Object value)是否包含指定的value
        isExist = map.containsValue("56");
        System.out.println(isExist);

        //int size();返回map中key-value对的个数
        System.out.println(map.size());

        //boolean isEmpty();测试map是否为空
        map.clear();
        System.out.println(map.isEmpty());

        //equals();判断是否相等
        Map map1 = new HashMap();
        map.put("AA",123);
        map.put(45,123);
        map.put("BB",56);

        System.out.println(map.equals(map1));
    }

3、元视图 *** 作(考虑遍历)的方法举例:

//不能直接使用迭代器iterator
    @Test
    public void test5(){
        Map map = new HashMap();
        map.put("AA",123);
        map.put(45,12);
        map.put("BB",56);

        //遍历所有的key集:keySet()
        Set set = map.keySet();
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println(next);
        }
        System.out.println("------------");
        //遍历所有的value集:values()
        Collection values = map.values();
        for (Object obj :values) {
            System.out.println(obj);
        }
        System.out.println("------------");
        //遍历所有的key-value:entrySet()
        //方式一:
        Set entrySet = map.entrySet();
        Iterator iterator1 = entrySet.iterator();
        while (iterator1.hasNext()) {
            Object next =  iterator1.next();
            //集合中的元素都是entry
            Map.Entry entry=(Map.Entry) next;
            System.out.println(entry.getKey()+"--->"+entry.getValue());
            //System.out.println(next);
        }
        System.out.println("------------");
        //方式二:
        Set Keyset = map.keySet();
        Iterator iterator2 = Keyset.iterator();
        while (iterator2.hasNext()) {
            Object key =  iterator2.next();
            Object value = map.get(key);
            System.out.println(key+"===="+value);
            //System.out.println(next);
        }
    }

常用方法总结:

添加:put(Object key,Object value)
删除:remove(Object key)
修改:putAll(Object key,Object value)
查询:get(Object key)
长度:size()
遍历:keySet() values()  entrySet()
六、Properties处理属性文件

举例:

public class PropertiesTest {
    //properties:常用来处理配置文件,key和value都是String类型
    public static void main(String[] args){
        FileInputStream fis= null;
        try {
            Properties pros = new Properties();
            fis = new FileInputStream("jdbc.properties");
            pros.load(fis);//加载流对应的文件

            String name=pros.getProperty("name");
            String password=pros.getProperty("password");
	           	 		         		System.out.println("name="+name+",password="+password);
            //jdbc文件写中文出现乱码: File--》Setting--》FileEncodings中改为UTF-8
            // 此时需要重新编写一个jdbc.properties文件
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(fis !=null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
七、Collections工具类常用方法



1、常用方法举例:

@Test
    public void test1(){
        List list=new ArrayList();
        list.add(123);
        list.add(345);
        list.add(345);
        list.add(345);
        list.add(-97);
        list.add(6);

        System.out.println(list);

        //reverse();反转list中元素的顺序
        //Collections.reverse(list);

        //shuffle();对list集合元素进行随机排序
        //Collections.shuffle(list);

        //sort();根据元素的自然顺序对指定list集合元素按升序排序
        //Collections.sort(list);

        //swap();将指定list集合中的i处元素和j处元素进行交换
        //Collections.swap(list,1,2);

        //frequency();判断某元素出现的频率
        //int frequency = Collections.frequency(list, 345);
        //System.out.println(frequency);

        System.out.println(list);
    }
@Test
    public void test2(){
        List list=new ArrayList();
        list.add(123);
        list.add(345);
        list.add(-97);
        list.add(6);

        /*
        报异常:IndexOutOfBoundsException: Source does not fit in dest
        List dest=new ArrayList();
        Collections.copy(dest,list);
         */
        List dest= Arrays.asList(new Object[list.size()]);
        System.out.println(dest.size());//list.size();
        Collections.copy(dest,list);

        System.out.println(dest);
        /*
        Collection 类中提供了多个synchronizedXxx() 方法,
        该方法可使将指定集合包装成线程同步的集合,从而可以解决
        多线程并发访问集合时的线程安全问题
         */
        //返回的list1即为线程安全的List
        List list1 = Collections.synchronizedList(list);
    }

;//list.size();
Collections.copy(dest,list);

    System.out.println(dest);
    /*
    Collection 类中提供了多个synchronizedXxx() 方法,
    该方法可使将指定集合包装成线程同步的集合,从而可以解决
    多线程并发访问集合时的线程安全问题
     */
    //返回的list1即为线程安全的List
    List list1 = Collections.synchronizedList(list);
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/790525.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-05
下一篇 2022-05-05

发表评论

登录后才能评论

评论列表(0条)

保存