当前位置:首页 > 服务端 > Java--集合大全List,Set,Map超详细讲解

Java--集合大全List,Set,Map超详细讲解

2022年11月09日 22:13:53服务端6

集合框架的作用:在实际开发中,我们经常会对一组相同类型的数据进行统一管理操作。在JDK1.2版本以后,JAVA提供了类集合的概念,封装了一组强大的集合框架API,在以后的开发中大大的提高了效率。

一.集合中分为三大接口:

Collection,Map,Iterator
集合类都位于java.util包中,在使用这些类时,首先要导入这些包。

图示:
Java--集合大全List,Set,Map超详细讲解 _ JavaClub全栈架构师技术笔记

  • Collection是单列集合的根接口,主要用于存储一系列符合某种规则的元素,它有两个重要的子接口List和Set。
  • List接口的特点是元素有序可重复
  • Set接口的特点是元素无序,不可重复
  • ArrayList和LinkedList是List接口的实现类
  • HashSet和TreeSet是Set接口的实现类

  • Map是双列集合的根接口,特用蓝色标注,用于存储具有键(Key),值(Value)映射关系的元素,每个元素都包含一个键-值对,在使用该集合时可以通过指定的键找的对应的值。
  • Map为独立接口
  • HashMap和TreeMap是Map接口的实现类

注: 假设Collection接口里有a,b,c三个方法,list接口里有d,f方法,set接口里有e,g方法,则它们的实现类里就拥有不同的方法。

二.Collection接口

1.接口定义:

public interface Collection<E> extends Iterable<E>

2.Colletion接口API文档:

Java--集合大全List,Set,Map超详细讲解 _ JavaClub全栈架构师技术笔记

3.接口常用方法:

方法作用 方法1 方法2 方法3
增加 add(E e) addAll(Colletion <? extends E> c)
删除 clear() remove(Object o) removeAll(Collection<?> c)
修改
查看 iterator() size()
判断 contains(Object o) equals(object o) isEmpty()

4.代码实现

class Test{
	public static void main(String[] args) {
		String a ="A";
		String b ="B";
		
	Collection<String> list1 = new ArrayList<String>();
	list1.add(a);  
	list1.add(b);
	
	Collection<String> list2 = new ArrayList<String>();
	list2.addAll(list1); 

	Iterator<String> it1 = list1.iterator();
	while(it1.hasNext()) {
		String str1 = it1.next();
		System.out.println(str1);
	}
	System.out.println("-------");
	
	Iterator<String> it2 = list2.iterator();
	while(it2.hasNext()) {
		String str = it2.next();
		System.out.println(str);
		}
   System.out.println("-------");

   System.out.println(list1==list2);
   System.out.println(list1.equals(list2));	
   System.out.println("-------");
   
   System.out.println(list1.contains(a));
}
}

Output:

A
B
-------
A
B
-------
false
true
-------
true


本段代码中,

  • 由于Collection是接口,所以无法实例化,而ArrayList类是Collection接口的间接实现类,所以可以通过ArrayList实例化:Collection< String > list1 = new ArrayList< String>();
  • System.out.println(list1.equals(list2));结果为true,说明Collection底层重写了equals()方法,使得eqals()比较两个list的值,而不是地址值
  • iterator()迭代器: Iterator< String> it1 = list1.iterator();表示创建了一个名为it1的迭代器,来迭代list1,并用泛型限制。it1.hasNext() 表示,it1是否有下一个元素,如果有下一个元素,返回true,进入while循环。String str1 = it1.next();表示,将元素用str1表示并将hasNext()的“指针”向下移。如果返回false,则表示没有下一元素,则不进入while循环。

三.List集合

List集合为列表类型,以线性方式存储对象。List集合中的元素允许重复,各元素的顺序就是对象插入的顺序。用户可以通过使用索引来访问List集合中的元素。

1主要方法

方法 说明
void add(int index,Object obj) 将obj插入调用列表,插入位置的下标由index传递。任何已存在的,在插入点以及插入点以后的元素将前移,因此没有元素被覆写。
Boolean addAll(int index,Collection c) 将c中的所有元素插入到调用列表中,插入点的下标由index传递。
Object get(int index) 返回指定下标的对象
Object set(int index,Object obj) 对由index指定的位置进行赋值
int indexOf(Object obj) 返回调用列表obj的第一个实例的下标。如果obj不是列表元素,返回-1.

对于由Collection定义的add()和addAll()方法外,List增加了方法add(int,Object)和addAll(int,Collection),这俩方法可以在指定的下标处插入元素。

List集合的特点就是存取有序,可以存储重复的元素,可以用下标进行元素的操作

2.ArrayList集合

ArrayList支持可随需要而增长的动态数组。在Java数组中,长度是固定的,因此在数组被创建后,不能修改长度,这意味着开发者需要实现知道数组的长度。但在一般情况下,只有在运行时才知道数组长度。为了解决这个问题,ArrayList因此而生。

2.1代码演示

class Test{
     
	public static void main(String[] args) {
     
		
	ArrayList<String> list1 = new ArrayList<>();
	
	System.out.println("list1初始长度为:"+ list1.size());
		list1.add("A");  
		list1.add("B");
		list1.add("C");
		list1.add("D");
		list1.add("E");
		list1.add("F");
		//将B2添加在list1的index=1的位置
		list1.add(1, "B2");
	System.out.println("list1加入元素后的大小:" + list1.size());
	System.out.println("list1元素为:"+ list1);
		list1.remove("A");
		list1.remove(2);
	System.out.println("list1删除元素后的大小:" + list1.size());
	System.out.println("list1元素为:" + list1);
}
}

Output:

list1初始长度为:0
list1加入元素后的大小:7
list1元素为:[A, B2, B, C, D, E, F]
list1删除元素后的大小:5
list1元素为:[B2, B, D, E, F]      // 需要移动数据,使得B2作为index=0的元素。

注意,list1开始为空,随着元素的加入,大小增加。当每个元素被删除时,大小会每次变小。

底层是使用数组实现,所以查询速度快,增删速度慢

3.ArrayList如何存入自定义的数据?

import java.util.ArrayList;
import java.util.Iterator;


public class Student{
     	
	
	private String name;
	private int id;
	
	public Student(){
     }
	
	public Student(String name, int id)
	{
     
		super();
		this.name = name;
		this.id = id;
	}

	public String getName()
	{
     
		return name;
	}
	public void setName(String name)
	{
     
		this.name = name;
	}
	public int getId()
	{
     
		return id;
	}
	public void setId(int id)
	{
     
		this.id = id;
	}	
	
}


class Test{
     
	public static void main(String []args) {
     
			
	  ArrayList<Student> list1 = new ArrayList<>();
		list1.add(new Student("lili",001));
		list1.add(new Student("haha",002)); //匿名对象存入集合
		list1.add(new Student("wawa",003));
			
		Iterator<Student> it=list1.iterator();
		while(it.hasNext()) {
     
			Student stu = it.next();
			System.out.println(stu.getName()+stu.getId());
				
			}

4.LinkedList集合

除了LinkedList继承的方法以外,它本身还定义了一些有用的方法。
addFirst()可以在列表头增加元素
addLast()可以在列表尾部增加元素
getFirst()可以获取第一个元素
removeFirst()可以删除第一个元素
removeLast()可以删除最后一个元素
getFirst() 返回此列表的第一个元素
getLast() 返回此列表的最后一个元素

LinkedList:是基于链表结构实现的,所以查询速度慢,增删速度快,提供了特殊的方法,对头尾的元素操作(进行增删查)

使用LinkedList实现栈

import java.util.LinkedList;

public class MyStack {
    private LinkedList<String> linkList = new LinkedList<String>();
    
    // 压栈
    public void push(String str){
        linkList.addFirst(str);
    }
    
    // 出栈
    public String pop(){
        return linkList.removeFirst();
    }
    
    // 查看
    public String peek(){
        return linkList.peek();
    }
    
    // 判断是否为空
    public boolean isEmpty(){
        return linkList.isEmpty();
    }
}

public class Test {
    public static void main(String[] args) {
    
        StackTest stack = new StackTest();
        stack.push("first");
        stack.push("second");
        stack.push("third");
        stack.push("forth");
        stack.push("fifth");
        // 取出
        while (!stack.isEmpty()){
            String pop = stack.pop();
            System.out.println(pop);
        }
       
    }

}

Output

        fifth
        fourth
        third
        second
        first

也可实现队列。

5.ArrayList与LinkedList

  • ArrayList和LinkedList顾名思义,ArrayList是Array(动态数组)的数据结构,相当于动态数组;LinkedList是Link(链表)的双向数据结构,也可当作堆栈、队列、双端队列
  • 对于随机访问List时(get和set操作),ArrayList比LinkedList的效率更高,因为LinkedList是线性的数据存储方式,所以需要移动指针从前往后依次查找。
  • 对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据(可以在上述ArrayList代码中体现)。
  • 两者缺点都为线性不安全

ArrayList和LinkedList线程不安全,在多线程中不建议使用。

四.Set集合

  • Set集合中的对象不按特定的方式排序,只是简单的将对象加入到集合中,但是Set集合不能包括重复对象
  • Set接口继承了Collection接口,因此也包含Collection接口的所有方法

1.哈希(hash)前序:

1.1哈希表:

散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

Java--集合大全List,Set,Map超详细讲解 _ JavaClub全栈架构师技术笔记

从上图中可以看出,哈希表实则是数组+链表的形式组成,数组指的上图中的01233456…,链表则指的是Java--集合大全List,Set,Map超详细讲解 _ JavaClub全栈架构师技术笔记

2 . Hashset集合

HashSet扩展自AbstractSet并且实现Set接口。
Java--集合大全List,Set,Map超详细讲解 _ JavaClub全栈架构师技术笔记

2.1 HashSet集合特点:

import java.util.HashSet;

class Test{
     
	public static void main(String []args) {
     
		HashSet<Integer> hs = new HashSet<>();
		
		hs.add(5);
		hs.add(2);
		hs.add(3);
		System.out.println(hs.add(4));
		System.out.println(hs.add(4));  //检验HashSet是否允许重复元素加入
		System.out.println(hs);    //检验HashSet是否有序
			
	}
}

Ouput:

true
false
[2, 3, 4, 5]

说明HashSet不允许重复,无序

2.2 放入自定义类型数据出现的问题


public class Student{
     	
	
	private String name;
	private int id;
	
	public Student(){
     }
	
	public Student(String name, int id)
	{
     
		super();
		this.name = name;
		this.id = id;
	}

	public String getName()
	{
     
		return name;
	}
	public void setName(String name)
	{
     
		this.name = name;
	}
	public int getId()
	{
     
		return id;
	}
	public void setId(int id)
	{
     
		this.id = id;
	}

	@Override
	public String toString()
	{
     
		return "Student [name=" + name + ", id=" + id + "]";
	}	
	
}

import java.util.HashSet;

class Test{
     
	public static void main(String []args) {
     
		HashSet<Student> hs = new HashSet<>();
		
		hs.add(new Student("yiyi",1));
		hs.add(new Student("feifei",2));
		hs.add(new Student("lili",3));

		System.out.println(hs.add(new Student("wawa",4)));	
		System.out.println(hs.add(new Student("wawa",4)));
		System.out.println(hs);
			
	}
}

Output:

true
true
[Student [name=yiyi, id=1], Student [name=wawa, id=4], Student [name=wawa, id=4], Student [name=lili, id=3], Student [name=feifei, id=2]]

问题:为什么是true,true。放入了两个一样的对象,为什么依然显示true,并且出现了出现了两次 Student [name=wawa, id=4], Student [name=wawa, id=4]。与上述HashSet不允许重复的特点相异。

为了解决这一问题,我们从底层原理说起

以int数据类型为例,假设我们要在hashSet中放入12,5,7,12,9,首先通过hashcode()方法计算它们的哈希值,根据哈希取模运算后(y=x%5),依次对应为2,0,2,2,4。 然后依次放入哈希表中,在放入时,有重复的数值比如2,则需要另外的方法equals()来判断是否相等,如果相等(重复)就不再放入,否则放入。
在存入int,string等类型时,Java帮我们写了hashcode()和equals()方法,所以才能显现出hashset的特点,无序单一性,我们存入自己定义的数据类型时,系统并没有相对于我们自定义数据类型的hashcode()和equals()方法。

因此,我们要想往hashSet里存入数据,就只能重写hashcode()和equals()方法!!

如何重写equals()和hashCode()方法

Java--集合大全List,Set,Map超详细讲解 _ JavaClub全栈架构师技术笔记
右键–>Source–>Generate hashCode() and equals()即可


public class Student{
     	
	
	private String name;
	private int id;
	
	public Student(){
     }
	
	public Student(String name, int id)
	{
     
		super();
		this.name = name;
		this.id = id;
	}

	@Override
	public int hashCode()
	{
     
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj)
	{
     
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (id != other.id)
			return false;
		if (name == null)
		{
     
			if (other.name != null)
				return false;
		}
		else if (!name.equals(other.name))
			return false;
		return true;
	}

	public String getName()
	{
     
		return name;
	}
	public void setName(String name)
	{
     
		this.name = name;
	}
	public int getId()
	{
     
		return id;
	}
	public void setId(int id)
	{
     
		this.id = id;
	}

	@Override
	public String toString()
	{
     
		return "Student [name=" + name + ", id=" + id + "]";
	}	
	
}

import java.util.HashSet;
import java.util.Iterator;



class Test{
     
	public static void main(String []args) {
     
		HashSet<Student> hs = new HashSet<>();
		
		hs.add(new Student("yiyi",1));
		hs.add(new Student("feifei",2));
		hs.add(new Student("lili",3));

		System.out.println(hs.add(new Student("wawa",4)));	
		System.out.println(hs.add(new Student("wawa",4)));
		System.out.println(hs);  //第一种打印方式,利用重写的toString()方法和Println()直接打印
		System.out.println("------------");
		for(Student s : hs) {
        //第二种打印方式,增强for循环
			System.out.println(s);
		}
		System.out.println("------------");   //第三种打印方式,利用Iteator
		Iterator<Student> it = hs.iterator();
			while(it.hasNext()) {
     
				Student s = it.next();
				System.out.println(s);
			}
		
		
			
	}
}

Output:

true
false
[Student [name=feifei, id=2], Student [name=wawa, id=4], Student [name=yiyi, id=1], Student [name=lili, id=3]]
------------
Student [name=feifei, id=2]
Student [name=wawa, id=4]
Student [name=yiyi, id=1]
Student [name=lili, id=3]
------------
Student [name=feifei, id=2]
Student [name=wawa, id=4]
Student [name=yiyi, id=1]
Student [name=lili, id=3]


3.LinkedHashSet集合

Java--集合大全List,Set,Map超详细讲解 _ JavaClub全栈架构师技术笔记
LinkedHashSet继承自HashSet
特点是:有序,唯一,效率高

4.TreeSet集合

TreeSet为使用树来进行储存的Set接口提供了一个工具,对象按升序储存,访问和检索是很快的。在存储了大量的需要进行快速检索的排序信息的情况下,TreeSet是一个不错的选择。
Java--集合大全List,Set,Map超详细讲解 _ JavaClub全栈架构师技术笔记
Java--集合大全List,Set,Map超详细讲解 _ JavaClub全栈架构师技术笔记

import java.util.Set;
import java.util.TreeSet;

class Test{
     
	public static void main(String []args) {
     
		Set<Integer> st = new TreeSet<>();
		st.add(1);
		st.add(4);
		st.add(5);
		st.add(2);
		System.out.println(st.add(2)); //验证是否可以添加重复元素
		System.out.println(st);		
	}
}

Output:

false
[1, 2, 4, 5]
  • false说明TreeSet集合不允许重复
  • [1, 2, 4, 5]说明,TreeSet对Integer数据类型进行升序排列
import java.util.Set;
import java.util.TreeSet;

class Test{
     
	public static void main(String []args) {
     
		Set<String> st = new TreeSet<>();
		st.add("java");
		st.add("c");
		st.add("pyhthon");
		st.add("c++");
		System.out.println(st.add("c++"));
		System.out.println(st);		
	}
}

Output:

false
[c, c++, java, pyhthon]
  • false说明TreeSet集合不允许重复
  • [c, c++, java, pyhthon]说明,TreeSet对String数据类型进行升序排列

说到按升序排列,肯定会想到内部比较器和外部比较器(如果不了解Java比较器可参考主页文章(https://blog.csdn.net/weixin_44551646/article/details/94741936)),事实上,Java在String和Integer类里重写了comparaTo方法,因此TreeSet可以对其进行升序排列。
Java--集合大全List,Set,Map超详细讲解 _ JavaClub全栈架构师技术笔记
Java--集合大全List,Set,Map超详细讲解 _ JavaClub全栈架构师技术笔记
那我们对自定义的TreeSet进行排序时,就需要自己重写比较方法。如果说没有重写任何比较器(内部或者外部)时,使用TreeSet进行操作会报错。

4.1使用内部比较器与TreeSet



public class Student implements Comparable{
     	
	
	 String name;
	 int age;
	 
	public Student(){
     }
	
	public Student(String name, int age)
	{
     
		super();
		this.name = name;
		this.age = age;
	}

	@Override
	public int compareTo(Object o)
	{
     
		Student stu =((Student)o);
		return this.age-stu.age;  //按照年龄升序排序
	}

	@Override
	public String toString()
	{
     
		return "Student [name=" + name + ", age=" + age + "]";
	}
}


import java.util.Set;
import java.util.TreeSet;

class Test{
     
	public static void main(String []args) {
     
		Set<Student> st = new TreeSet<>();
		st.add(new Student("lili",18));
		st.add(new Student("nana",19));
		st.add(new Student("huahua",20));
		st.add(new Student("baba",10));
		
		System.out.println(st);		
	}
}

Output:

[Student [name=baba, age=10], Student [name=lili, age=18], Student [name=nana, age=19], Student [name=huahua, age=20]]

我们看的Output中的对象年龄按照从小到大的方式排列。

4.2使用外部比较器与TreeSet

import java.util.Comparator;

public class Student {
     	
	
	 String name;
	 int age;
	 
	public Student(){
     }
	
	public Student(String name, int age)
	{
     
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString()
	{
     
		return "Student [name=" + name + ", age=" + age + "]";
	}


}

class OutsideCompare implements Comparator{
     

	@Override
	public int compare(Object o1, Object o2)
	{
     
		Student st1 = ((Student) o1);
		Student st2 = ((Student) o2);
		return st1.age-st2.age;
	}
	
}

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

class Test{
     
	public static void main(String []args) {
     
		
		OutsideCompare com = new OutsideCompare();
		
		Set<Student> st = new TreeSet<>(com);
		st.add(new Student("lili",18));
		st.add(new Student("nana",19));
		st.add(new Student("huahua",20));
		st.add(new Student("baba",10));
		
		System.out.println(st);		
	}
}

注意⚠️:

  • 使用外部比较器时,在测试类里要创建外部比较器对象OutsideCompare com = new OutsideCompare(); 也可以用多态的形式Comparator com =new OutsideCompare();如果这里有疑问,强烈推荐去看主页文章,关于内部比较器和外部比较器(https://blog.csdn.net/weixin_44551646/article/details/94741936)
  • 我们需要把创建出的外部比较器对象com传入TreeSet中,Set<Student> st = new TreeSet<>(com);即括号里的com。
    因为通过TreeSet源码可知Java--集合大全List,Set,Map超详细讲解 _ JavaClub全栈架构师技术笔记
    TreeSet需要传入Comparator当作参数!!

四.Map集合

1. HashMap集合

Map集合没有继承Collection接口,其提供的是键到值的映射。Map不能包含相同的键,每个键只能映射一个值。键还决定了储存对象在映射中的储存位置。

HashMap集合特点:单一,无序

Map.Entry<K,V>
映射项(键-值对)K=key,V=value

异常:

  1. NoSuchElementException-----当调用的映射中没有元素存在时
  2. ClassCastException-------对象与映射中的元素不兼容时
  3. NullPointerException-------如果试图使用映射不允许使用的null对象时
  4. UnsupportedOperationException-----当试图改变一个不允许修改的映射时

常用方法:
Java--集合大全List,Set,Map超详细讲解 _ JavaClub全栈架构师技术笔记
总结一下:

  • 添加功能:V put (K key,V value)
  • 获取功能:V get(Object key), Set< K > keySet(), Collection< V> values(), int size()
  • 判断功能:boolean containsKey(object key),boolean containsValue(Object value),boolean isEmpty()
  • 删除功能:void clear(),V remove(Object key)
  • 遍历功能:Set<Map.Entry<K,V>> entrySet()

黑体为重点讲解方法


1.1添加功能

import java.util.HashMap;


class Test{
	public static void main(String []args) {
		
		
		HashMap<String, String> map = new HashMap<>();
		
		System.out.println(map.put("ABC001", "Kevin"));
		System.out.println(map.put("ABC002", "Lily"));
		System.out.println(map.put("ABC001", "Clack"));  //此处Key与第一个重复!!
	
		
		System.out.println(map);		
	}
}

Output:

null
null
Kevin
{ABC001=Clack, ABC002=Lily}

上述代码,由此可见,添加功能:V put (K key,V value),就是将key映射到value,如果key存在,则覆盖value,并将原来的value返回


1.2获取功能(Value):


import java.util.Collection;
import java.util.HashMap;


class Test{
     
	public static void main(String []args) {
     
		
		
		HashMap<String, String> map = new HashMap<>();
		map.put("ABC001", "Kevin");
		map.put("ABC002", "Lily");
		map.put("ABC001", "Clack");
		map.put("ABC003", "Bob");
		map.put("ABC004", "Zombie");

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

Output:

Clack
Lily
Bob
Zombie

Collection< V> values()获取到所有Value的值


1.2获取功能(Key):

import java.util.HashMap;
import java.util.Set;


class Test{
     
	public static void main(String []args) {
     
		
		
		HashMap<String, String> map = new HashMap<>();
		map.put("ABC001", "Kevin");
		map.put("ABC002", "Lily");
		map.put("ABC001", "Clack");
		map.put("ABC003", "Bob");
		map.put("ABC004", "Zombie");

		//Set<K> keySet()
		Set<String> keys = map.keySet();
		for(String key: keys) {
     
			System.out.println(key);
		}
	}
}

Output:

ABC001
ABC002
ABC003
ABC004

Set< K> keySet()以Set的形式返回所有的key


1.3遍历功能(一):

获取每一个Key,通过Key来找Value

import java.util.HashMap;
import java.util.Set;


class Test{
     
	public static void main(String []args) {
     
		
		
		HashMap<String, String> map = new HashMap<>();
		map.put("ABC001", "Kevin");
		map.put("ABC002", "Lily");
		map.put("ABC001", "Clack");
		map.put("ABC003", "Bob");
		map.put("ABC004", "Zombie");

		//获取所有key
		Set<String> keys = map.keySet(); 
		for(String key: keys) {
     
		     //通过Key来找Value
			String value = map.get(key); 
			System.out.println("ID:"+key+"--Name: "+value);
		}
	}
}

Output:

ID:ABC001--Name: Clack
ID:ABC002--Name: Lily
ID:ABC003--Name: Bob
ID:ABC004--Name: Zombie

1.3遍历功能(二):

通过(entry)中间人Set<Map.Entry<K,V>> entrySet() 来寻找Key和Value

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


class Test{
     
	public static void main(String []args) {
     
		
		
		HashMap<String, String> map = new HashMap<>();
		map.put("ABC001", "Kevin");
		map.put("ABC002", "Lily");
		map.put("ABC001", "Clack");
		map.put("ABC003", "Bob");
		map.put("ABC004", "Zombie");
        
		//获取所有中间人entrys
		Set<Map.Entry<String, String>> entrys =map.entrySet();
		//遍历所有entrys用Map.Entry<String, String>类型的entry接收
		for(Map.Entry<String, String> entry:entrys) {
     
			String key = entry.getKey();
			String value = entry.getValue();
			
			System.out.println("ID:"+key+"--Name: "+value);
		}
		}
	}


Output:

ID:ABC001--Name: Clack
ID:ABC002--Name: Lily
ID:ABC003--Name: Bob
ID:ABC004--Name: Zombie

1.4放入自定义类型数据

注意⚠️,如果要放入自定义类型的数据当作key,一定要重写hashcode()和equals()防止重复。

2.HashTable与HashMap关联

HashTable出现在JDK1.0, 线程安全,因为不能存入null类型数据
HashMap出现在JDK1.5,线程不安全,因为能存入null

3. LinkedHashMap集合

用法跟HashMap基本一致,它是基于链表和哈希表结构的所以具有存取有序,键不重复的特性,存的顺序和遍历出来的顺序是一致的

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;


class Test{
     
	public static void main(String []args) {
     
		
		
		LinkedHashMap<String, String> map = new LinkedHashMap<>();
		map.put("ABC001", "Kevin");
		map.put("ABC003", "Lily");
		map.put("ABC001", "Clack");
		map.put("ABC002", "Bob");
		map.put("ABC004", "Zombie");
        
		//获取所有中间人entrys
		Set<Map.Entry<String, String>> entrys =map.entrySet();
		//遍历所有entrys用Map.Entry<String, String>类型的entry接收
		for(Map.Entry<String, String> entry:entrys) {
     
			String key = entry.getKey();
			String value = entry.getValue();
			
			System.out.println("ID:"+key+"--Name: "+value);
		}
		}
	}


Output:

ID:ABC001--Name: Clack
ID:ABC003--Name: Lily
ID:ABC002--Name: Bob
ID:ABC004--Name: Zombie

4.TreeMap集合

TreeMap与TreeSet类似,都需要重写比较器(外部比较器+内部比较器)
TreeMap集合特点:单一,有序

下面举例,外部比较器与匿名对象类结合

import java.util.Comparator;
import java.util.Map.Entry;
import java.util.TreeMap;

public class Test {
     
    public static void main(String[] args) {
     
        
        TreeMap<Student,String> map = new TreeMap<>(new Comparator<Student>() {
     
            @Override
            public int compare(Student o1, Student o2) {
     
                if (o1 == o2){
     
                    return 0;
                }
                int result = o1.getAge() - o2.getAge();
                if (result == 0){
     
                    return o1.getName().compareTo(o2.getName());
                }
                return result;
            }
        });
        
        map.put(new Student("A", 12), "JAVA");
        map.put(new Student("C", 50), "IOS");
        map.put(new Student("D", 32), "JS");
        map.put(new Student("B", 32), "PHP");
        map.put(new Student("E", 12), "C++");
        
        
        for (Entry<Student,String> entry : map.entrySet()){
     
            System.out.println(entry.getKey()+"==="+entry.getValue());
        }
        
    }
}

Output:

 Student [name=A, age=12]===JAVA
Student [name=E, age=12]===C++
Student [name=B, age=32]===PHP
Student [name=D, age=32]===JS
Student [name=C, age=50]===IOS

注意⚠️:
1.存入的时候添加了两个张三,如果Map中键相同的时候,当后面的值会覆盖掉前面的值
2.TreeMap 取出来的顺序是经过排序的,是根据compara方法排序的
3.新建的比较器对象应传入TreeMap中,该段代码中,用匿名对象new comparator< Student>(){……}传入TreeMap<Student,String> map = new TreeMap<>()最后的括号内,即TreeMap<Student,String> map = new TreeMap<>(new comparator< Student>(){……重写的compare方法……});

内部比较器与TreeMap结合的例子,请看上面TreeSet有关例子。

作者:66Kevin
来源链接:https://blog.csdn.net/weixin_44551646/article/details/94295677

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/server/69230.html

标签: ListJavaMap
分享给朋友:

“Java--集合大全List,Set,Map超详细讲解” 的相关文章

java基础知识讲解(一)数据类型和运算符

java基础知识讲解(一)数据类型和运算符

Java是一种强类型语言,每个变量都必须声明其数据类型。 Java的数据类型可分为两大类:基本数据类型(primitive data type)和引用数据类型(reference data type)。 Java中定义了3类8种基本数据类型 数值型- b...

全面了解 Java 原子变量类

📦 本文以及示例源码已归档在 javacore 一、原子变量类简介 为何需要原子变量类 保证线程安全是 Java 并发编程必须要解决的重要问题。Java 从原子性、可见性、有序性这三大特性入手,确保多线程的数据一致性。 确保线程安全最...

Java 内存模型

Java 内存模型

📦 本文以及示例源码已归档在 javacore Java 内存模型(Java Memory Model),简称 JMM。 JVM 中试图定义一种 JMM 来屏蔽各种硬件和操作系统的内存访问差异,以实现让 Java 程序在各种平台下都能达到一致的内存访问效果。...

Java 日志框架详解

Java 日志框架详解

1. JUL学习 JUL全称Java util Logging是java原生的日志框架,使用时不需要另外引用第三方类库,相对其他日志框 架使用方便,学习简单,能够在小型应用中灵活使用。 1.1 架构介绍 Loggers...

java比较语句常犯错误和三个数比较大小

1.忘了大括号 解决: 任何if else语句后面加大括号,哪怕只有一句 2.忘了分号 if后面不能有分号 3.代码分格 Scanner in=new Scanner(System.in); int x; int y; int z;...

java中将英尺换算为身高

java中将英尺换算为身高

直接上代码 如图所示便是身高的换算,你学到了吗?、 int foot; double inch; Scanner in=new Scanner(System.in); foot=in.nextInt(); inch=in.nextDouble...

Java开发手册精华总结

Java开发手册精华总结

阿里 Java 开发手册的思考总结 一个优秀的工程师和一个普通的工程师的区别,不是满天飞的架构图,他的功底体现在所写的每一行代码上。 -- 毕玄 1. 命名风格 【书摘】类名用 UpperCamelCase 风格,比如 DO/BO/VO...

java泛型通配符详解

java泛型通配符详解

前言 泛型带来的好处 泛型中通配符 常用的 T,E,K,V,? ?无界通配符 上界通配符 < ? extends E> 下界通配符 < ? super E>...

java空指针异常:java.lang.NullPointException

一.什么是java空指针异常     我们都知道java是没有指针的,这里说的"java指针"指的就是java的引用,我们不在这里讨论叫指针究竟合不合适,而只是针对这个异常本身进行分析。空指针就是空引用,java空指针异常就是引用本身为空,却调用了方...

java高级

java高级

  Java动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类。代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架。下...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。