集合 MAP 详解

本文详细介绍了Java集合框架中的Map接口及其常见实现类,包括HashMap和TreeMap。HashMap基于哈希表实现,允许快速存取,而TreeMap则通过红黑树实现排序和去重。文章还讨论了Map接口的常用方法,如put、remove和get,并对比了两种遍历Map的不同方式。此外,还提到了可变参数和增强for循环在Java中的应用。
摘要由CSDN通过智能技术生成

集合  MAP

Map 接口

Map本身是接口,存储的是键值对,一个元素是一个KEY和VALUE对,Key必须是唯一的(必点实现了去重),value值是随意的,是可以重复的.

1. HashMap :底层是哈希表,线程不安全的

2. TreeMap:底层是二叉树,线程不安全的

方法:

1. 增加:put(key,value),如果存入重复的Key,会替换之前的value,返回之前的value

2. 删除:remove(Object key)  根据key删除元素,返回值就是被删掉的值,void clear()  删除全部  != null

3. 获取:get(Object key)  根据key查找元素,int size()  获取键值对的个数

4. 常用的判断:boolean isEmpty()  //空map!=null;boolean containsKey(K key) 是否包含当前的key;boolean containsValue(V value) 是否包含当前的value

两种遍历方法:

1. 遍历方法一:Set keySet()

1.原理:先得到所有的key,放入一个Set中,利用Set的迭代器进行遍历得到key,在利用key获取value

2.步骤:

第一步:先得到装着key的set: Set set = map.keySet();keySet();将Map中所有的键存入Set集合中,通过集合中迭代器的方式进行遍历。

第二步:遍历set,得到key,再根据key获取value:

Iterator iterator = set.iterator();

while (iterator.hasNext()) {

String key = iterator.next();

System.out.println(“key:”+key+"   value:"+map.get(key));

}

2. 遍历方法二:Set<Map.Entry<K,V>> entrySet()

1.原理:先得到所有的entry,放入一个Set中,利用Set的迭代器进行遍历得到entry实体,在利用entry的方法获取key和value

2.步骤:

第一步:先得到装着Entry实体的set:Set<Map.Entry<String,String>> set =  map.entrySet();

第二步:遍历set,得到entry实体,再调用entry实体对象的方法获取key和value:Iterator<Map.Entry<String,String>> iterator = set.iterator();

while (iterator.hasNext()) {

Map.Entry<String, String> entry = iterator.next();

//通过setValue可以将map的原始值改变,但是一般在使用entrySet的时候,是进行遍历.不进行值的改变.

//entry.setValue(“bingbing”);

System.out.println(“key1:”+entry.getKey()+"    value1:"+entry.getValue());

}

3.Set<Map.Entry<K,V>> entrySet() //返回此映射中包含的映射关系的 Set 视图。 Map.Entry表示映射关系。entrySet():迭代后可以e.getKey(),e.getValue()取key和value。返回的是Entry接口 。

遍历说明:

说明:

①Set keySet():返回值是个只存放key值的Set集合(集合中无序存放的),迭代后只能通过get()取key。

②Set<Map.Entry<K,V>> entrySet():返回映射所包含的映射关系的Set集合(一个关系就是一个键-值对),就是把(key-value)作为一个整体一对一对地存放到Set集合当中的。迭代后可以e.getKey(),e.getValue()取key和value。返回的是Entry接口

效率比较:1.通过查看源代码发现,调用这个方法keySetMap.keySet()会生成KeyIterator迭代器,其next方法只返回其key值2.而调entrySetMap.entrySet()方法会生成EntryIterator 迭代器,其next方法返回一个Entry对象的一个实例,其中包含key和value. 3.二者在此时的性能应该是相同的,但方式一再取得key所对应的value时,此时还要访问Map的这个方法,这时,方式一多遍历了一次table

entry,是Map里面的静态接口,为什么怎么做?entry对应的是一个实体,成了内部接口的话,map对象可以直接调用(map.entry.getKey)

MAP通过转成collection实现遍历

Map和Set底层是一样的,只是Set没有管value

HashMap:去重,因为HashMap的底层与HashSet的底层实现一样,只是对HashMap去重的时候,操作的是key

注意一::HashMap可以实现排序:因为他的底层数据结构是由数组+链表+二叉树共同实现的.所以可以排序.同时这样做的目的是提高数据存储的效率.

注意二:面试题:

1. hashMap与HashTable的区别?线程安全,HashTable value不能为空

2. HashMap的底层实现:在JDK1.6,JDK1.7中,HashMap采用位桶+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,HashMap采用位桶+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。

TreeMap:去重和排序,底层与TreeSet一致,在进行排序去重的时候就是去操作key.

注意点:

1.什么类型的数据类型可以作为key?

a:实现了Comparable接口的compareTo()方法

b:实现了Comparator接口的compare()方法

可以的代表:String,包装类,自定义的实现了要求的类

不可以的代表:数组,ArrayList,LinkedList(如果给他们建立的比较器也可以比较,但是不建议使用)

2.元素可不可以作为key,跟元素内部的成员没有关系


public class Demo5 {

    public static void main(String[] args) {

        TreeMap<Dog, String> map = new TreeMap<>();

        //如果没有重写compareTo或者compare方法,put内部无法调用元素的这两个方法.所以会报错

        map.put(new Dog(), "haha");

    }

}



class Dog implements Comparable<Dog>{

    //2.元素可不可以作为key,跟元素内部的成员有没有关系

    Object object;

    @Override

    public int compareTo(Dog o) {

        // TODO Auto-generated method stub

        return 0;

    }

    

}



可变参数:参数的个数可以改变

1. 作用:简化代码,简化操作


public class Demo6 {

    public static void main(String[] args) {

        sum(2, 3);//值传递

        //址传递

        int[] arr = {3,4,5};

        sum(arr);

        //可变参数

        

        //可变参数的特点

        //1.给可变参数传值的实参可以直接写,个数不限制,内部会自动的将他们放入可变数组中.

        sum1(5,6,7,8,9,3,3,4);

        //2.当包括可变参数在内有多个参数时,可变参数必须放在最后面,并且一个方法中最多只能有一个可变参数

        

        //3.当可变参数的方法与固定参数的方法是重载关系时,调用的顺序,固定参数的优先于可变参数的.

        sum3(2,3);

    }

    

    //求两个数的和

    //值传递

    public static int sum(int a,int b) {

        return a+b;

    }

    //址传递

    public static int sum(int[] a) {

        int sum = 0;

        for (int i = 0; i < a.length; i++) {

            sum+=a[i];

        }

        return sum;

    }

    //通过可变参数

    //构成:数据类型+...    实际上就是数据类型[]  即:int[]

    public static int sum1(int... a) {

        int sum = 0;

        for (int i = 0; i < a.length; i++) {

            sum+=a[i];

        }

        return sum;

    }

    //2.当包括可变参数在内有多个参数时,可变参数必须放在最后面,并且一个方法中最多只能有一个可变参数

    public static int sum2(float b,int... a) {

        int sum = 0;

        for (int i = 0; i < a.length; i++) {

            sum+=a[i];

        }

        return sum;

    }

    //3.当可变参数的方法与固定参数的方法是重载关系时,调用的顺序,固定参数的优先于可变参数的.

    public static int sum3(int a, int b) {

        System.out.println("a");

        int sum = 0;

        return sum;

    }

    public static int sum3(int... a) {

        System.out.println("b");

        int sum = 0;

        return sum;

    }

}



增强for循环:可以遍历的内容有:数组,Collection,Map.但是Map不能直接遍历

- 原理:每次遍历开始后,会自动从数组中依次取出一个元素放入前面的变量中,当次循环的操作使用的就是这个元素.遍历完成之后,会自动进行第二次遍历.一直到数组的末尾.所有元素遍历结束.循环停止.

- 遍历Map


    for (String key : map.keySet()) {

            

        }



    for (Map.Entry<String, String> entry: map.entrySet()) {

            

        }

Collections:封装了大量操作的Collection的工具

1. 使用Collection排序:


package test;



import java.util.ArrayList;

import java.util.Collections;

import java.util.Comparator;





public class Collections1{

    



    public static void main(String[] args) {

        //要求:存储多个数据,可排序,可重复

        ArrayList<String> list = new ArrayList<>();

        list.add("java");

        list.add("java1haha");

        list.add("java2BigData");

        list.add("java3ok");

        list.add("java2");

        System.out.println(list);

        

        //使用Collections排序

        //第一种排序:默认按照字典进行排序

        //注意:要想list中的元素可以按照字典排序,元素必须实现Comparable接口

        Collections.sort(list);//加入的是String 但是String 已经实现了Comparable

        System.out.println("默认的字典排序:"+list);

        

        //按照从短到长排序

        //使用比较器

        ComStrWithLength1 comStrWithLength = new ComStrWithLength1();

        Collections.sort(list, comStrWithLength);

        System.out.println("从短到长排序:"+list);

        

        //按照从长到短排序

        Comparator<String> comparator1 =  Collections.reverseOrder(comStrWithLength);

        Collections.sort(list, comparator1);

        System.out.println("从长到短排序:"+list);

        

        //倒叙字典排序

        Comparator<String> comparator2 =  Collections.reverseOrder();        

        Collections.sort(list, comparator2);

        System.out.println("倒叙字典排序:"+list);

        

        Collections.reverse(list);

        System.out.println("现有顺序的反转排序:"+list);

        

        //求最大值

        String max = Collections.max(list, comStrWithLength);

        System.out.println(max);

    }

}



class ComStrWithLength1 implements Comparator<String>{

    @Override

    public int compare(String o1, String o2) {

        int num = o1.length()-o2.length();

        return num==0?o1.compareTo(o2):num;

    }

}



哈希表

hashMap的存值原理?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值