Java中Map集合的用法

一、前言

在Java中,Map是一个接口,用于存储键值对(key-value)的集合。Map中的每一个元素都是一个键值对,并且不允许有重复的键。键(key)是唯一的,并且与值(value)相关联。

实现类:Java标准库提供了几个实现Map接口的类,包括HashMap、LinkedHashMap、TreeMap、Hashtable、ConcurrentHashMap等。

          

  • HashMap:基于哈希表的实现,通常用于快速查找和插入。
  • LinkedHashMap:维护了插入顺序的HashMap。
  • TreeMap:基于红黑二叉树的实现,自然排序或自定义排序。
  • Hashtable:线程安全的HashMap,但性能较低。
  • ConcurrentHashMap:线程安全的HashMap,支持高并发。

二、HashMap的基本语句

HashMap是Java集合框架中提供了一个实现Map接口的类。基于哈希表实现。

特点:键值对储存、哈希表结构、不保证顺序、允许使用null键和null值(null键只能有一个,因为键是唯一的)、初始容量(哈希表的大小)和加载因子(决定何时调整哈希表大小的参数)、非线程安全 、迭代功能、扩容机制。

性能:在理想情况下,HashMap的查找、插入和删除操作的平均时间复杂度都是O(1),但这是在哈希函数分布均匀且没有哈希冲突的情况下。如果哈希函数设计的不好,或者数据量非常大,哈希冲突或增多,性能收到影响。

1、创建HashMap 

HashMap map=new HashMap();

2、添加值

map.put("CN","中国");
map.put(null,"空值");
map.put("NULL",null);

3、覆盖原来的value(键唯一)

map.put("CN","中国香港");

4、取值(只能通过key查找value)

        System.out.println(map.get("CN"));
        System.out.println(map.get(null));
        System.out.println(map.get("NULL"));

5、元素个数

System.out.println(map.size());

6、清空元素

map.clear();

7、判断是否包含某个键

System.out.println(map.containsKey("CN"));

8、遍历

Set<Map.Entry<String,String>> entries=map.entrySet();
for (Map.Entry<String,String> entry:entries){
            System.out.println("key:"+entry.getKey()+"value:"+entry.getValue());
        }

 9、获取value值

Collection<String> values=map.values();

10、for遍历

        for (String value:values){
            System.out.println(value);
        }

11、遍历键

        Set<String> keys=map.keySet();
        for (String ky:keys){
            System.out.println(map.get(ky));
        }

12、forEach(lamada表达式:(形参)->{方法体})

        map.forEach((key,value)->{
            System.out.println("key:"+key+"value:"+value);
        });

13、判断是否为空

System.out.println(map.isEmpty());

14、元素删除(元素删除后,根据key获得的是null)

        map.remove("CN");
        System.out.println(map.get("CN"));

15、元素替换

        map.replace(null,"这是个新的值");
        System.out.println(map.get(null));
1>练习 :

源码:

package day14;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Practice1 {
    public static void main(String[] args) {
        HashMap map=new HashMap();
        map.put("Allen","JDBC");
        map.put("Lucy","math");
        map.replace("Lucy","CoreJava");
        map.put("zhangsan","JSP");
        map.put("ls","JSP");
//        遍历
        Set<Map.Entry<String,String>> entries=map.entrySet();
        for (Map.Entry<String,String> entry:entries){
            System.out.println("key:"+entry.getKey()+"     "+"value:"+entry.getValue());
        }
        System.out.println("-----------------------------------------------");
        for (Map.Entry<String,String> entry:entries){
            if (entry.getValue().equals("JSP")){
                System.out.println(entry.getKey());
            }
        }


    }
}

运行结果:

 

这里因为每个老师都是唯一的,但是可能会有很多个老师教同一个科目,根据键值对规则,老师->key,科目 ->value。

 

三、Hashtable的基本语句

Hashtable和HashMap的区别:

  • HashMap的key和value允许为null,Hashtable的key和value不允许为null
  • HashMap线程不安全,Hashtable线程安全

 1、创建Hashtable集合对象

Hashtable table = new Hashtable();

2、集合添加值

        table.put("CN","中国");
        table.put("USA","美国");
        table.put("US","英国");

3、元素个数

System.out.println(table.size());

4、清空集合

table.clear();

5、元素删除

table.remove("US");

6、元素替换

table.replace("USA","America");

7、遍历

(1)

        Collection<String> values=table.values();
        for (String value:values){
            System.out.println(value);
        }

(2)

        Set<String> keys=table.keySet();
        for (String ky:keys){
            System.out.println(table.get(ky));
        }

(3)

        table.forEach((key,value)->{
            System.out.println("key:"+key+"value:"+value);
        });

(4)

        Set<Map.Entry<String,String>> entries=table.entrySet();
        for (Map.Entry<String,String> entry:entries){
            System.out.println("key:"+entry.getKey()+"value:"+entry.getValue());
        }

8、迭代枚举

//      把Map集合的value转化为枚举
        Enumeration<String> ens=table.elements();
//        迭代枚举接口
        while (ens.hasMoreElements()){
            System.out.println(ens.nextElement());
        }

Hashtable与HashMap的基本语句其实差不多,遍历方法有一点点出入 

四、TreeMap基本语句

1、创建集合

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

2、添加值

        map.put("b",2);
        map.put("a",1);
        map.put("d",4);
        map.put("e",5);
        map.put("c",3);

3、获取大于或等于key映射的实体对象

        Map.Entry entry=map.ceilingEntry("d");//等于
        System.out.println(entry.getKey()+"--"+entry.getValue());

4、严格大于

        entry=map.higherEntry("d");
        System.out.println(entry.getKey()+"--"+entry.getValue());

5、获取大于或等于key的键key

      System.out.println(map.ceilingEntry("d"));

6、获取第一个实体对

        entry=map.firstEntry();
        System.out.println(entry.getKey()+"--"+entry.getValue());

7、获取第一个键

        String key=map.firstKey();
        System.out.println(key);

8、获取最后一个实体对

        entry=map.lastEntry();
        System.out.println(entry.getKey()+"--"+entry.getValue());

9、 获取最后一个key

System.out.println(map.lastKey());

10、截取map集合的一部分

        SortedMap sm=map.subMap("b","d");
        Set<Map.Entry> entries=sm.entrySet();
        for (Map.Entry en:entries){
            System.out.println("key"+en.getKey()+"--"+"value"+en.getValue());
        }

11、获取小于或等于指定key的实体对象

        entry=map.floorEntry("d");
        System.out.println(entry.getKey()+"--"+entry.getValue());

12、严格小于

        entry=map.lowerEntry("d");
        System.out.println(entry.getKey()+"--"+entry.getValue());

13、获取小于或等于key的键

entry=map.floorEntry("d");

五、ConcurrentHashMap基本语句

1、创建集合对象

ConcurrentHashMap<Integer,Integer> con = new ConcurrentHashMap();

2、添加数据

        con.put(1,3);
        con.put(2,5);
        con.put(3,7);
        con.put(4,9);
        con.put(6,7);

3、forEach遍历

//        获取一个检索时间
        long before=System.currentTimeMillis();
        con.forEach(5,(key,value)->{
            System.out.println("key:"+key+",value:"+value);
        });
        long after=System.currentTimeMillis();
        System.out.println("总消耗时间"+(after-before));

4、search搜索

        String result=con.search(5,(key,value)->{
           if (key==3){
               return "存在3的key值";
           }
           return null;
        });
        System.out.println(result);

5、reduce

        Integer val=con.reduce(5,(key,value)->{
            return key+value;
        },(o1,o2)->{
            return o1*o2;
        });
        System.out.println(val);

 六、Collections

1、创建集合

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

2、同时添加多个数据

Collections.addAll(list,1,2,3,34,5,6,7,8);

3、遍历

        for (int i=0;i<list.size(); i++){
            System.out.println(list.get(i));
        }

4、集合中搜索数据(搜索方式:二分搜索)

        int index=Collections.binarySearch(list,3);
        System.out.println("位置:"+index);//没搜到,结果为负数

5、数据复制

        List<Integer> newList=new ArrayList<>();
        Collections.addAll(newList,0,0,0,0,0,0,0,0);
        Collections.copy(newList,list);

6、数据填充(这里是将里面所有的数据都变成11)

Collections.fill(list,11);

7、最小值

        Integer min=Collections.min(list);
        System.out.println(min);

8、最大值

        Integer max=Collections.max(list);
        System.out.println(max);

9、集合数据翻转

        Collections.reverse(list);
        for (int i=0;i<list.size(); i++){
            System.out.println(list.get(i));
        }

10、将数据随机打乱

        Collections.shuffle(list);
        for (int i=0;i<list.size(); i++){
            System.out.println(list.get(i));
        }

11、交换

 Collections.swap(list,2,3);//2,3为下标

将线程不安全的集合转化为线程安全的集合:关键字synchronizedList

七、案例练习

 

源码:

Employee:

package day15.practice1;

public class Employee {
    private String name;
    private String sal;
    private MyDate birthday;
    public Employee(String name,String sal,MyDate birthday){
        this.name=name;
        this.sal=sal;
        this.birthday=birthday;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSal() {
        return sal;
    }

    public void setSal(String sal) {
        this.sal = sal;
    }

    public MyDate getBirthday() {
        return birthday;
    }

    public void setBirthday(MyDate birthday) {
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", sal='" + sal + '\'' +
                ", birthday=" + birthday +
                '}';
    }
}

MyDate:

package day15.practice1;

public class MyDate {
    private int year;
    private int month;
    private int day;
    public MyDate(int year,int month,int day){
        this.year=year;
        this.month=month;
        this.day=day;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }

    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = day;
    }
}

Test:

package day15.practice1;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class Test {
    public static void main(String[] args) {
        Employee emp1=new Employee("zs","男",new MyDate(2000,2,17));
        Employee emp2=new Employee("ls","男",new MyDate(2004,12,30));
        Employee emp3=new Employee("zs","女",new MyDate(2002,8,17));
//        将这些对象放入ArrayList集合中
        ArrayList<Employee> arrayList=new ArrayList<>();
        arrayList.add(emp1);
        arrayList.add(emp2);
        arrayList.add(emp3);

        Collections.sort(arrayList, new Comparator<Employee>() {
            @Override
            public int compare(Employee o1, Employee o2) {
                int s=0;
                int s1=0;
                int s2=0;
                if (o1.getName().length()-o2.getName().length()==0){

                    for (int i=0;i<o1.getName().length();i++){
                        s=o1.getName().charAt(i)-o2.getName().charAt(i);
                    }
                    if (s!=0){
                        return s;
                    }
                    else {
                        s1=o1.getBirthday().getYear()-o2.getBirthday().getYear();
                        if (s1!=0){
                            return s1;
                        }
                        else {
                            s2=o1.getBirthday().getMonth()-o2.getBirthday().getMonth();
                            if (s2==0){
                                return o1.getBirthday().getDay()-o2.getBirthday().getDay();
                            }
                            else
                                return 0;
                        }
                    }
                }
                else
                    return 0;

            }
        });
        for (Employee employee:arrayList){
            System.out.println(employee);
        }

    }
}

运行结果: 

八、小结

  • List

   -ArrayList : 数组 (动态数组),线程不安全
   特点: 添加删除中间元素效率低,查询效率高。
   -LinkedList: 双链表
   特点: 添加元素效率高,查询效率低。
   -Vector: 数组,线程安全

  • Set

   -HashSet: 哈希表(数组+链表+红黑二叉树)

   -TreeSet:红黑二叉树
   优点: 实现自然排序,查找效率稍高, 添加元素效率低。

  • Map

    1.HashMap:哈希表

    方法:
    void clear() :从这张地图中删除所有的映射。 
    boolean containsKey(Object key) :如果此映射包含指定键的映射,则返回 true 。  
    boolean containsValue(Object value) :如果此地图将一个或多个键映射到指定值,则返回 true 。  
    Set<Map.Entry<K,V>> entrySet() :返回此地图中包含的映射的Set视图。  
    void forEach(BiConsumer<? super K,? super V> action) :对此映射中的每个条目执行给定的操作,直到所有条目都被处理或操作引发异常。  
    V get(Object key) :返回到指定键所映射的值,或 null如果此映射包含该键的映射。
    boolean isEmpty() :如果此地图不包含键值映射,则返回 true 。  
    Set<K> keySet() :返回此地图中包含的键的Set视图。 
    V put(K key, V value) :将指定的值与此映射中的指定键相关联。  
    V remove(Object key) :从该地图中删除指定键的映射(如果存在)。  
    boolean remove(Object key, Object value) :仅当指定的密钥当前映射到指定的值时删除该条目。  
    V replace(K key, V value) :只有当目标映射到某个值时,才能替换指定键的条目。  
    boolean replace(K key, V oldValue, V newValue) :仅当当前映射到指定的值时,才能替换指定键的条目。 
    int size() :返回此地图中键值映射的数量。  
    Collection<V> values() :返回此地图中包含的值的Collection视图。 

 

 

 

 

 

  • 28
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值