Java集合Map常用子类简介

admin2025-06-25 17:10:03世界杯比赛视频

Map(映射,存储的是“键-值”映射表,“键”是不能重复的)

如果键重复,则相当于修改对应键的值。

Map接口定义方法

int size();//获取map大小

boolean isEmpty();//size==0?

boolean containsKey(Object var1);//查看是否包含某个键

boolean containsValue(Object var1);//查看是否包含某个值

V get(Object var1);//跟据key获取值

V put(K var1, V var2);//Map接口有两个类型参数,K和V,分别表示键(Key)和值(Value)的类型,按Key值var1保存值var2,如果键重复,则相当于修改对应键的值。

V remove(Object var1);//移除键对应的值

void putAll(Map var1);//批量保存

void clear();//清空map

Set keySet();//获取Map中键的集合

Collection values();//获取Map中值的集合

Set> entrySet();//获取Map中值的键值对(遍历)

public interface Entry {

K getKey();//键

V getValue();//值

V setValue(V var1);//修改键

boolean equals(Object var1);

int hashCode();

}

方法使用简介(以HashMap实现类为例)

HashMap 存储的数据是没有顺序的,键或值可以为null

/**

* Map

*/

public class Demo {

public static void main(String[] args) {

//key //value//Map

Map map = new HashMap<>();

map.put(1, "aaa");//添加元素

map.put(2, "www");

map.put(3, "assaa");

map.put(4, "qqq");

map.put(5, "ggg");

map.put(1, "nnn");//修改元素

map.put(6, "ooo");

map.put(7, "232");

map.put(12, "ffds");

System.out.println(map.size() + "");//获取大小//8

//////////////////////

System.out.println(map.isEmpty());//size==0?//false

//////////////////////

System.out.println(map.containsKey(10));//查看是否包含某个键//false

/////////////////////

System.out.println(map.containsValue("ooo"));//查看是否包含某个值//true

/////////////////////

System.out.println(map.get(3));//跟据key获取值//assaa

/////////////////////

map.remove(12);//移除键对应的值

System.out.println(map.containsKey(12));//false

/////////////////////

Map map1 = new HashMap<>();

map.put(100, "999");//添加元素

map.put(110, "222");//添加元素

map.put(120, "333");//添加元素

map.putAll(map1);//批量保存

Set integers = map.keySet();//获取Map中键的集合

System.out.println(integers);//[1, 2, 3, 4, 100, 5, 6, 7, 120, 110]

////////////////////////

Collection values = map.values();//获取Map中值的集合

System.out.println(values);//[nnn, www, assaa, qqq, 999, ggg, ooo, 232, 333, 222]

////////////////////////

Set> entries = map.entrySet();//迭代

Iterator> iterator = entries.iterator();

while (iterator.hasNext()) {

Map.Entry mapNext = iterator.next();

System.out.print(mapNext.getKey() + "-->" + mapNext.getValue() + "\t");

//1-->nnn 2-->www 3-->assaa 4-->qqq 100-->999 5-->ggg 6-->ooo 7-->232 120-->333 110-->222

}

}

}

额外延伸SparseArray

Hashtable

Hashtable和HashMap的区别

Hashtable里面的方法几乎都是同步的,线程安全,HashMap则没有,但效率高。(同ArrAyList和Vector)

Hashtable不允许存放null值(键和值都不可以),而HashMap可以

相同点

存放元素无序

LinkedHashMap继承自HashMap

LinkedHashMap 实现与 HashMap 的不同之处在于,LinkedHashMap 维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,

该迭代顺序可以是插入顺序或者是访问顺序(参考以下代码理解)

不是线程安全

案例

/**

* LinkedHashMap

* LinkedHashMap和HashMap区别

* LinkedHashMap 保存了记录的插入顺序

* HashMap 则无序存放

*/

public class Demo {

public static void main(String[] args) {

//关注点一:看添加之后的输出结果对比

System.out.println("关注点一:LinkedHashMap输出:");

LinkedHashMap linkedHashMap = new LinkedHashMap();

linkedHashMap.put(1, "aaa");//添加元素

linkedHashMap.put(7, "www");

linkedHashMap.put(5, "ggg");

linkedHashMap.put(1, "nnn");//修改元素

linkedHashMap.put(6, "ooo");

linkedHashMap.put(7, "232");

linkedHashMap.put(12, "ffds");

Set> entries = linkedHashMap.entrySet();

Iterator> iterator = entries.iterator();

while (iterator.hasNext()) {

Map.Entry next = iterator.next();

System.out.print(next.getKey() + "-->" + next.getValue() + "\t");

//1-->nnn 7-->232 5-->ggg 6-->ooo 12-->ffds

}

System.out.println();

System.out.println("关注点一:HashMap输出:");

Map map = new HashMap<>();

map.put(1, "aaa");//添加元素

map.put(7, "www");

map.put(5, "ggg");

map.put(1, "nnn");//修改元素

map.put(6, "ooo");

map.put(7, "232");

map.put(12, "ffds");

Set> entries1 = map.entrySet();//迭代

Iterator> iterator1 = entries1.iterator();

while (iterator1.hasNext()) {

Map.Entry mapNext = iterator1.next();

System.out.print(mapNext.getKey() + "-->" + mapNext.getValue() + "\t");

//1-->nnn 5-->ggg 6-->ooo 7-->232 12-->ffds

}

/////////////////////////////////////////////////////////////////

//关注点二:换一个构造方法

System.out.println(); //10 大小//0.75还不清楚//true代表使用访问顺序

LinkedHashMap linkedHashMap1 = new LinkedHashMap<>(10, 0.75f, true);

linkedHashMap1.put(1, "aaa");//添加元素

linkedHashMap1.put(7, "www");

linkedHashMap1.put(5, "ggg");

linkedHashMap1.put(1, "nnn");//修改元素

linkedHashMap1.put(6, "ooo");

linkedHashMap1.put(7, "232");

linkedHashMap1.put(12, "ffds");

System.out.println("=======================================================");

System.out.println("更换构造方法后未使用元素之前输出");

Set> entries2 = linkedHashMap1.entrySet();

Iterator> iterator2 = entries2.iterator();

while (iterator2.hasNext()) {

Map.Entry next = iterator2.next();

System.out.print(next.getKey() + "-->" + next.getValue() + "\t");

//5-->ggg 1-->nnn 6-->ooo 7-->232 12-->ffds

}

System.out.println();

//关键点来了

System.out.println(linkedHashMap1.get(6));//ooo

System.out.println(linkedHashMap1.get(12));//ffds

System.out.println("更换构造方法后未使用元素之后输出");

Set> entries3 = linkedHashMap1.entrySet();

Iterator> iterator3 = entries3.iterator();

while (iterator3.hasNext()) {

Map.Entry next = iterator3.next();

System.out.print(next.getKey() + "-->" + next.getValue() + "\t");

//5-->ggg 1-->nnn 7-->232 6-->ooo 12-->ffds

}

}

}

运行结果:

LinkedHashMap延伸(用途)

最近最少使用LRUcache

最近最少使用LRUcache

最近最少使用LRUcache

最近最少使用LRUcache

TreeMap

使用了二叉权的数据结构,key是有序,保存其唯一性用到了hashCode()、equals()以及比较器(唯一性判断,键排序同TreeSet)

案例

/**

* TreeMap:

* 使用了二叉权的数据结构,key是有序,保存其唯一性用到了hashCode()、equals()以及比较器(唯一性判断同HashSet)

*/

public class Demo {

public static void main(String[] args) {

//来个稍微复杂点的:存放一个Student链表

//TreeMapK类必须实现Comparable接口,用于比较排序

TreeMap> map = new TreeMap<>();

List students1 = new ArrayList<>();

students1.add(new Student("小花", 23));

students1.add(new Student("小黑", 20));

students1.add(new Student("小鱼", 29));

students1.add(new Student("小小", 23));

map.put("小班", students1);

List students2 = new ArrayList<>();

students2.add(new Student("大花", 230));

students2.add(new Student("大黑", 200));

students2.add(new Student("大鱼", 290));

students2.add(new Student("大大", 230));

map.put("大班", students2);

Set>> entries = map.entrySet();

for (Map.Entry> entry : entries) {

List s = entry.getValue();

System.out.println(entry.getKey() + ":" + s);

}

}

}

class Student {

private String name;

private int age;

public Student(String name, int age) {

this.age = age;

this.name = name;

}

@Override

public String toString() {

return "[" + this.name + ":\t" + this.age + "]";

}

}

运行结果

案例二

/**

* TreeMap自定义比较器

*

* 案例:按地区存放学校

* 建模

* //School

* //Area

*/

public class Demo {

public static void main(String[] args) {

List schools1 = new ArrayList();

schools1.add(new School("10", "火星1"));

schools1.add(new School("11", "火星2"));

schools1.add(new School("12", "火星3"));

List schools2 = new ArrayList();

schools2.add(new School("20", "北京1"));

schools2.add(new School("21", "北京2"));

schools2.add(new School("22", "北京3"));

//如果TreeMap的K是自定义类型 ,则此类必须实现Comparable接口,用于比较排序

Map> clsMap = new TreeMap>();

clsMap.put(new Area("1004", "火星"), schools1);

clsMap.put(new Area("1002", "北京"), schools2);

Set>> entrySet = clsMap.entrySet();

for (Map.Entry> cls : entrySet) {

List s = cls.getValue();

System.out.println(cls.getKey().id+"\t" + cls.getKey().name + ":" + s);

}

}

}

//

class Area implements Comparable {

//名字

String name;

//编号

String id;

public Area(String id, String name) {

this.id = id;

this.name = name;

}

@Override

public int compareTo(Area o) {

//先比较班级的名称,如果名称相同,再比较id(也可以先比较id再比较name)

int r = this.name.compareTo(o.name);

return r == 0 ? this.id.compareTo(o.id) : r;

}

@Override

public String toString() {

return this.name + "\t";

}

}

class School {

private String id;

private String name;

public School(String id, String name) {

this.id = id;

this.name = name;

}

@Override

public String toString() {

return "School[id=" + id + ", name=" + name + "]";

}

}

运行结果

补充

List、Set、Map是否继承自Collection接口?

List、Set 是,Map 不是。Map是键值对映射容器,与List和Set有明显的区别,而Set存储的零散的元素且不允许有重复元素(数学中的集合也是如此),List是线性结构的容器,适用于按数值索引访问元素的情形。

阐述ArrayList、Vector、LinkedList的存储性能和特性。

ArrayList 和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector中的方法由于添加了synchronized修饰,因此Vector是线程安全的容器,但性能上较ArrayList差,因此已经是Java中的遗留容器。LinkedList使用双向链表实现存储(将内存中零散的内存单元通过附加的引用关联起来,形成一个可以按序号索引的线性结构,这种链式存储方式与数组的连续存储方式相比,内存的利用率更高),按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。Vector属于遗留容器(Java早期的版本中提供的容器,除此之外,Hashtable、Dictionary、BitSet、Stack、Properties都是遗留容器),已经不推荐使用,但是由于ArrayList和LinkedListed都是非线程安全的,如果遇到多个线程操作同一个容器的场景,则可以通过工具类Collections中的synchronizedList方法将其转换成线程安全的容器后再使用

Collection和Collections的区别?

Collection是一个接口,它是Set、List等容器的父接口;Collections是个一个工具类,提供了一系列的静态方法来辅助容器操作,这些方法包括对容器的搜索、排序、线程安全化等等

List、Map、Set三个接口存取元素时,各有什么特点?

List以特定索引来存取元素,可以有重复元素。Set不能存放重复元素(用对象的equals()方法来区分元素是否重复)。Map保存键值对(key-value pair)映射,映射关系可以是一对一或多对一。

友情链接