Java底子入门 【第八章 聚集】(三)

[复制链接]
发表于 2026-1-18 01:34:38 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
1.Set聚集



    • Set概述

java.util.Set 接口继续了 Collection 接口,是常用的一种聚集范例。相对于之前学习的List聚集,Set聚集特点如下:

除了具有 Collection 聚集的特点,还具有本身的一些特点:

Set是一种无序的聚集

Set是一种不带下标索引的聚集Set是一种不能存放重复数据的聚集

重点学习的Set实现类:

HashSet 底层借助哈希表实现TreeSet 底层借助二叉树实现

注意,TreeSet是Set接口的子接口SortedSet的实现类

底子案例:

实例化一个Set聚集,往内里添加元素并输出,注意观察聚集特点(无序、不重复)

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

public class Test071_SetBasic {

public static void main(String[] args) {

 
//1.实例化Set聚集,指向HashSet实现类对象Set<String> set = new HashSet<>();

set.add("hello1"); set.add("hello2"); set.add("hello3"); set.add("hello4");

set.add("hello5");   //添加失败 重复元素set.add("hello5");   //添加失败 重复元素

//加强for循环遍历

for(String obj : set){ System.out.println(obj);

}

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

//迭代器遍历

Iterator<String> it = set.iterator(); while(it.hasNext()){

Object obj = it.next(); System.out.println(obj);

}

}

 
}

//输出结果:hello1 hello4 hello5 hello2 hello3

-----------------

通过以上代码和运行结果,可以看出Set范例聚集的特点:无序、不可重复

HashSet

java.util.HashSet 是Set接口的实现类,它利用哈希表(Hash Table)作为其底层数据布局来存储数据。

HashSet特点:

无序性:HashSet中的元素的存储序次与插入序次无关

HashSet利用哈希表来存储数据,哈希表根据元素的哈希值来确定元素的存储位置,而哈希值是根据元素的内容盘算得到的,与插入序次无关。

唯一性:HashSet中不允许重复的元素,即每个元素都是唯一的

允许null元素:HashSet允许存储null元素,但只能存储一个null元素,HashSet中不允许重复元素

高效性:HashSet的插入、删除和查找操纵的时间复杂度都是O(1)

哈希表通过将元素的哈希值映射到数组的索引来实现快速的插入、删除和查找操纵。

底子案例1:

实例化HashSet对象,往内里插入多个字符串,验证HashSet特点。

package com.briup.chap08.test;

import java.util.HashSet; import java.util.Set;

public class Test072_Basic {

 
public static void main(String[] args) {

//1.实例化HashSet对象

Set<String> set = new HashSet<>();

//2.往聚会合添加元素set.add("hello"); set.add("world"); set.add("nihao"); set.add("hello"); set.add(null); set.add(null);

System.out.println("size: " + set.size());

//3.遍历

for (String str : set) { System.out.println(str);

}

}

}

//运行结果:size: 4 null

world

nihao

hello

根据结果可知,HashSet无序、唯一、null值可存在。

 
元素插入过程:

当向HashSet中插入元素时,先获取元素的hashCode()值,再查抄HashSet中是否存在类似哈希值的元素,假如元素哈希值唯一,则直接插入元素

假如存在类似哈希值的元素,会调用元素的equals()方法来进一步判定元素是否是类似。假如类似,则不会插入重复元素;假如差别,则插入

方法复习:

hashCode() 方法是 Object类 中的一个方法,它返回一个 int 范例的哈希码值

通常环境下, hashCode() 方法会根据对象的属性值盘算一个哈希码值(重写自界说类中 hashCode方法 )

假如两个对象的hashCode值差别,则两个对象的属性值肯定差别

假如两个对象的hashCode值类似,则两个对象的属性值大概类似,也大概差别

结论:假如要往HashSet聚集存储自界说类对象,那么肯定要重写自界说类中的hashCode方法和equals方法。

TreeSet

TreeSet是SortedSet(Set接口的子接口)的实现类,它基于红黑树(Red- Black Tree)数据布局实现。

TreeSet特点:

有序性:插入的元素会自动排序,每次插入、删除或查询操纵后,TreeSet会自动调解元素的序次,以保持有序性。

唯一性:TreeSet中不允许重复的元素,即聚会合的元素是唯一的。假如实行插入一个已经存在的元素,该操纵将被忽略。

动态性:TreeSet是一个动态聚集,可以根据须要随时添加、删除和修改元素。插入和删除操纵的时间复杂度为O(log n),此中n是聚会合的元素数目。

高效性:由于TreeSet底层接纳红黑树数据布局,它具有快速的查找和插入性能。对于有序聚集的操纵,TreeSet通常比HashSet更高效。

入门案例1:

准备一个TreeSet聚集,放入多个Integer元素,观察是否自动举行排序。

public class Test073_Integer {

public static void main(String[] args) {

//1.实例化聚集对象

Set<Integer> set = new TreeSet<>();

//2.添加元素set.add(3); set.add(5); set.add(1); set.add(7);

//3.遍历

for(Integer obj : set) { System.out.println(obj);

}

}

}

//输出结果:

1

3

5

7

标题分析:

根据非常提示可知错误缘故原由是: Person 无法转化成 Comparable ,从而导致ClassCastException非常 。

为什么会如许呢?

TreeSet是一个有序聚集,存储数据时,肯定要指定元素的排序规则,有两种指定的方式,详细如下:

TreeSet排序规则:自然排序(元素所属范例要实现 java.lang.Comparable 接口)比力器排序上述2个案例中,Integer存如TreeSet没有报错,是由于Integer类已经实现自然排序,而Person类既没有实现自然排序,也没有额外指定比力器排序规则。

 
1)TreeSet:自然排序


假如一个类,实现了 java.lang.Comparable 接口,并重写了 compareTo方法 ,那么这个类的对象就是可以比力巨细的。

public interface Comparable<T> { public int compareTo(T o);

}

compareTo方法说明:

int result = this.属性.compareTo(o.属性);

result的值大于0,阐明this比o大result的值小于0,阐明this比o小result的值便是0,阐明this和o相称

元素插入过程:

 
当向TreeSet插入元素时,TreeSet会利用元素的 compareTo() 方法来比力元素之间的巨细关系。根据比力结果,TreeSet会将元素插入到符合的位置,以保持有序性。假如两个元素相称( compareTo() 方法返回0),TreeSet会以为这是重复的元素,只会保存一个。


案例展示:


利用自然排序(先按name升序,name类似则按age降序)办理上述案例标题。

底子Person类:

package com.briup.chap08.bean;

//界说Person类,实现自然排序

public class Person implements Comparable<erson> { private String name;

private int age;

public Person() {}

public Person(String name, int age) { this.name = name;

this.age = age; }

public String getName() { return name;

}

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

}

public int getAge() { return age;

}

public void setAge(int age) {

 
}

@Override

public String toString() {

return "erson [name=" + name + ", age=" + age + "]"; }

//重写方法,指定比力规则:先按name升序,name类似则按age降序

@Override

public int compareTo(Person o) {

//注意:字符串比力须要利用compareTo方法

int r = name.compareTo(o.name); if(r == 0) {

r = o.age - this.age; }

return r; } }

测试类:

package com.briup.chap08.test;

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

import com.briup.chap08.bean.Person;

//自然排序测试

public class Test073_Comparable {

public static void main(String[] args) {

//1.实例化TreeSet

Set<erson> set = new TreeSet<>();

//2.添加元素

set.add(new Person("zs",21)); set.add(new Person("ww",20)); set.add(new Person("zs",21)); set.add(new Person("tom",19)); set.add(new Person("tom",23)); set.add(new Person("jack",20));

//3.遍历聚集

for (Person person : set) { System.out.println(person);

}

 
}

//输出结果:

Person [name=jack, age=20]

Person [name=tom, age=23]

Person [name=tom, age=19]

Person [name=ww, age=20]

Person [name=zs, age=21]

 
增补内容1:Integer类中重写compare源码

可以看出,Integer的俩个对象比力巨细,着实就是比力Integer对象对应的int值的巨细

注意,compareTo方法返回值代表的寄义(三种环境:正数、负数、零)增补内容2:整形、浮点型、字符串自然排序规则

 
对于整型、浮点型元素,它们会按照从小到大的序次举行排序。对于字符串范例的元素,它们会按照字典序次举行排序。

注意事项:compareTo方法的放回结果,只关心正数、负数、零,不关心详细的值是多少

2)TreeSet:比力器排序

思索:假如上述案例中Person类不是自界说类,而是第三方提供好的(不可以修改源码),那么怎样实现排序规则的指定?

我们可以可以利用比力器(Comparator)来自界说排序规则。

比力器排序步调:

创建一个实现了Comparator接口的比力器类,并重写此中的 compare() 方法

该方法界说了元素之间的比力规则。在 compare() 方法中,我们可以根据元素的属性举行比力,并返回负整数、零或正整数,来表现元素之间的巨细关系。

创建TreeSet对象时,将比力器对象作为参数转达给构造函数,如许,TreeSet会根据比力器来举行排序。

TreeSet类构造器增补:

//实例化TreeSet类对象时,须要额外传入一个比力器类对象

public TreeSet(Comparator<? super E> comparator) {

this(new TreeMap<>(comparator)); }

 
jcompare方法阐明:

int result = compare(o1, o2);

result的值大于0,表现升序result的值小于0,表现降序

result的值便是0,表现元素相称,不能插入


注意,这里和自然排序的规则是一样的,只关心正数、负数、零,不关心详细的值是多少


案例说明:

利用比力器排序,对上述案例中Person举行排序,要求先按age升序,age类似则按name降序。

 
底子类须要解释掉自然排序接口:

//界说Person类,实现自然排序

public class Person /* implements Comparable<erson> */ { private String name;

private int age;

public Person() {}

public Person(String name, int age) { this.name = name;

this.age = age; }

public String getName() { return name;

}

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

}

public int getAge() { return age;

}

public void setAge(int age) { this.age = age;

}

@Override

public String toString() {

return "erson [name=" + name + ", age=" + age + "]"; }

//重写方法,指定比力规则

//   @Override

//   public int compareTo(Person o) {  } }

//先按name升序,name类似则按age降序

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

if(r == 0) {

r = o.age - this.age; }

return r;测试类:

 
package com.briup.chap08.test;



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

import java.util.TreeSet;

import com.briup.chap08.bean.Person;

//比力器排序测试

public class Test073_Comparator {

public static void main(String[] args) {

//1.准备自界说比力器对象

//   匿名内部类情势

Comparator<erson> comp = new Comparator<erson>() {

//重写比力算法:先按按age升序,age类似则按name降序

@Override

public int compare(Person o1, Person o2) {

int r = o1.getAge() - o2.getAge(); if(r == 0) {

//注意:字符串比力须要利用compareTo方法

r = o2.getName().compareTo(o1.getName());

}

return r;

 
};

//2.实例化TreeSet,传入自界说比力器对象

Set<erson> set = new TreeSet<>(comp);

//3.添加元素

set.add(new Person("zs",21)); set.add(new Person("ww",20)); set.add(new Person("zs",21)); set.add(new Person("tom",19)); set.add(new Person("tom",23)); set.add(new Person("jack",20));

//4.遍历聚集

for (Person person : set) { System.out.println(person);

} }

//输出结果:

Person [name=tom, age=19]

Person [name=ww, age=20]

Person [name=jack, age=20]

Person [name=zs, age=21]

Person [name=tom, age=23]

注意:假如同时利用自然排序和比力器排序,比力器排序将覆盖自然排序。

 
2.自然排序:

利用元素类实现Comparable接口,并重写此中的 compareTo() 方法元素会按照其自身的比力规则举行排序

自然排序是默认的排序方式,可以直接利用TreeSet或Collections.sort()方法举行排序

只能有一种自然排序方式比力器排序:

利用Comparator对象来界说元素之间的比力规则

可以自界说排序规则,不依赖于元素类的实现Comparable接口

须要创建一个实现Comparator接口的比力器类,并重写此中的 compare()方法

可以有多个比力器,根据须要选择差别的比力器举行排序

可以通过传入Comparator对象给TreeSet或Collections.sort()方法来举行比力器排序

自然排序和比力器排序都有本身的应用场景。自然排序实用于元素类已经实现了Comparable接口,而且盼望按照元素自身的比力规则举行排序的环境。比力器排序实用于须要自界说排序规则,大概元素类没有实现Comparable接口的情

况。

LinkedHashSet

LinkedHashSet 是 HashSet 的一个子类,具有 HashSet 的高效性能和唯一性特性,而且保持了元素的插入序次,其底层基于哈希表和链表实现。

案例展示:

 
实例化一个LinkedHashSet聚集对象,存入多个String字符串,观察是否唯一及序次存储。

package com.briup.chap08.test;

import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Set;

public class Test074_LinkedHashSet {

public static void main(String[] args) {

// 1.实例化LinkedHashSet

Set<String> set = new LinkedHashSet<>();

// 2.添加元素set.add("bbb"); set.add("aaa"); set.add("abc"); set.add("bbc"); set.add("abc");

// 3.迭代器遍历

Iterator<String> it = set.iterator(); while (it.hasNext()) {

System.out.println(it.next()); }

}

}

//运行结果:

bbb

aaa

abc

bbc



    • Set小结

                       
聚集类

                       
                       
特点

                       
                       
示例

                       
                       

                       
HashSet

                       
                       
基于哈希表实现,无序聚集,不允许重复元素。

                       
                       
Set set = new HashSet<>();

                       
                       

                       
TreeSet

                       
                       
基于红黑树实现,有序聚集,不允许重复元素。

                       
                       
Set set = new TreeSet<>();

                       
                       

                       

                       
LinkedHashSet

                       
                       

                       
基于哈希表和链表实现,按插入序次排序,不允许重复元素。

                       
                       
Set set = new LinkedHashSet<> ();

                       
3.Map聚集

很多时间,我们会碰到成对出现的数据,比方,姓名和电话,身份证和人,IP和域名等等,这种成对出现,而且逐一对应的数据关系,叫做映射。java.util.Map<K,  V> 接口,就是专门处置处罚这种映射关系数据的聚集范例。

Map聚集是一种用于存储键值对(key-value)映射关系的聚集类。它提供了一种快速查找和访问数据的方式,此中每个键都是唯一的,而值可以重复。

Map概述

Collection接口为单列聚集的根接口,Map接口为双列聚集的根接口。Map聚集与Collection聚集,存储数据的情势差别:


 
Map聚集特点:

存储元素时,必须以key-value(键值对)的方式举行

键唯一性:Map集

合中的键是唯一的,每个键只能对应一个值

可重复值:Map聚会合的值可以重复,差别的键可以关联类似的值

高效的查找和访问:通过给定键key值(唯一),可以快速获取与之对应的value值

Map聚集内部利用哈希表或红黑树等数据布局来实现高效的查找和访问

Map接口常用方法(注意泛型K代表Key,范型V代表Value):

//把key-value存到当前Map聚会合

V put(K key, V value)

//把指定map中的全部key-value,存到当前Map聚会合

void putAll(Map<? extends K,? extends V> m)

//当前Map聚会合是否包罗指定的key值

boolean containsKey(Object key)

//当前Map聚会合是否包罗指定的value值

boolean containsValue(Object value)

 
//清空当前Map聚会合的全部数据

void clear()

//在当前Map聚会合,通过指定的key值,获取对应的value

V get(Object key)

//在当前Map聚会合,移除指定key及其对应的value

V remove(Object key)

//返回当前Map聚会合的元素个数(一对key-value,算一个元素数据)

int size()

//判定当前Map聚集是否为空

boolean isEmpty()

//返回Map聚会合全部的key值

Set<K> keySet()

//返回Map聚会合全部的value值

Collection<V> values()

//把Map聚会合的的key-value封装成Entry范例对象,再存放到set聚会合,并返回

 
24 Set<Map.Entry<K,V>> entrySet()

Map聚集实现类:

Java提供的Map聚集实现类,常见的包罗HashMap、TreeMap、LinkedHashMap等。它们在内部实现和性能方面有所差别,可以根据详细需求选择恰当的实现类。

HashMap ,底层借助哈希表实现,元素的存取序次不能包管同等。由于要包管键的唯一、不重复,须要重写键所属类的hashCode()方法、equals()方法

(紧张,最常用)

Hashtable :和之前List聚会合的 Vector 的功能类似,可以在多线程环境中,包管聚会合的数据的操纵安全(线程安全)

LinkedHashMap :该类是 HashMap 的子类,存储数据接纳的哈希表布局+链表布局。通过链表布局可以包管元素的存取序次同等(存入序次就是取出顺序)

TreeMap :该类是 Map 接口的子接口 SortedMap 下面的实现类,和TreeSet 类似,它可以对key值举行排序,同时构造器也可以吸取一个比力器对象作为参数。支持key值的自然排序和比力器排序俩种方式(支持key排序)

根本方法利用案例:

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

public class Test081_MapBasic {

//双列聚集 存放  id-name

public static void main(String[] args) {

//1.创建HashMap聚集对象,并添加元素Map<Integer,String> map = new HashMap<>();

//注意,利用put方法添加键值对map.put(1, "zs"); map.put(2, "ls"); map.put(4, "rose"); map.put(3, "jack");

map.put(2, "lucy"); //lucy 会把 ls覆盖掉

//2.输出聚集元素个数

//System.out.println(map); System.out.println("size: "+map.size());

//3.判定key和value是否存在

System.out.println("key 2: " + map.containsKey(2)); System.out.println("value ls: " +

map.containsValue("ls"));

//4.根据key获取value

String name = map.get(3); System.out.println("3: " + name);

//5.根据key删除键值对map.remove(3); System.out.println(map);

 
}

//运行结果:

size: 4

key 2: true value ls: false 3: jack

{1=zs, 2=lucy, 4=rose}

 
​​​​​​​Map遍历

Map聚集提供了2种遍历方式。

1)第一种遍历思绪


借助Map中的keySet方法,获取一个Set聚集对象,内部包罗了Map聚会合全部的key,进而遍历Set聚集获取每一个key值,再根据key获取对应的value。

keySet遍历案例:

2)第二种遍历思绪

 
借助Map中的entrySet方法,获取一个Set对象,内部包罗了Map聚会合全部的键值对,然后对键值对举行拆分,得到key和value举行输出。


Map 接口 entrySet() 方法分析:将 Map 聚会合的每一组key-value(键值对)都封装成一个 Entry 范例对象,而且把这些个 Entry 对象存放到Set聚会合,并返回。

entrySet遍历案例:对前面案例中的map聚集对象举行遍历。import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.Map.Entry;public class Test082_Each {

 
//双列聚集 存放  id-name

public static void main(String[] args) {

//1.创建HashMap聚集对象,并添加元素

Map<Integer,String> map = new HashMap<>();

map.put(1, "zs"); map.put(2, "ls"); map.put(4, "rose"); map.put(3, "jack");

map.put(2, "lucy"); //lucy 会把 ls覆盖掉

//2.第二种遍历

//   获取全部的key-value键值对,得到一个Set聚集

Set<Entry<Integer,String>> entrySet = map.entrySet();

//   遍历Set聚集

for (Entry<Integer, String> entry : entrySet) {

//   拆分键值对中的key和value Integer key = entry.getKey(); String value = entry.getValue();

System.out.println("id: " + key + " name: " + value);

}

}

}



//运行结果:

 
id: 1 name: zs id: 2 name: lucy id: 3 name: jack id: 4 name: rose

 
​​​​​​​HashMap

HashMap底层借助哈希表实现,元素的存取序次不能包管同等。

HashMap存储的键值对时,假如键范例为自界说类,那么一样平常须要重写键所属类的hashCode()和equals()方法(紧张,最常用)。

HashMap特点:

键唯一

值可重复

无序性

线程不安全

键和值的允许利用null【重点影象】

/ 4.第一种遍历方法

Set<Student> keySet = map.keySet(); for (Student key : keySet) {

System.out.println(key + ": " + map.get(key)); }

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

// 第二种方式遍历

Set<Entry<Student, String>> entrySet = map.entrySet(); for (Entry<Student, String> entry : entrySet) {

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

}

}

}



//运行结果:

size: 6

Student(ww,67)是否存在: true是否存在 009: false

remove(Student(lucy, 70)): 019

--------------- null: 002

Student [name=rose, age=82]: 005 Student [name=zs, age=78]: 010 Student [name=tom, age=86]: null Student [name=ww, age=67]: 002

---------------

省略...

 
结论:key范例假如为自界说范例,重写其hashCode和equals方法!

HashMap中add(key,value)时,须要判定key是否存在(先hashCode再equals)

HashMap中containsKey(key)时,同样要借助hashCode和equals方法HashMap中remove(key)时,同样要借助hashCode和equals方法

Hashtable

Hashtable是Java中早期的哈希表实现,它实现了Map接口,并提供了键值对的存储和访问功能。

Hashtable特点:

JDK1.0提供,接口方法较为复杂,后期实现了Map接口

线程安全:Hashtable是线程安全的,相对于HashMap性能稍低

键和值都不能为null:假如实利用用null作为键或值,将会抛出NullPointerException

 
哈希表实现:和HashMap一样,内部利用哈希表数据布局来存储键值对

案例展示:


实例化Hashtable<Student, String>对象,添加元素并遍历。

package com.briup.chap08.test;

import java.util.Enumeration; import java.util.Hashtable;

import com.briup.chap08.bean.Student;

public class Test084_Hashtable {

public static void main(String[] args) {

// 1.实例化HashMap对象,此中key范例为自界说Student

Hashtable<Student, String> map = new Hashtable<>();

// 2.往聚会合添加元素

//  map中插入键值对,调用key所属类的hashCode和equals方法举行判定是否重复

map.put(new Student("zs", 78), "010"); map.put(new Student("rose", 82), "005"); map.put(new Student("lucy", 70), "009");

map.put(new Student("lucy", 70), "019"); // 类似key,只能保存一项,"019"会覆盖"009"

map.put(new Student("ww", 67), "002");

// 注意:Hashtable中key和value不能为null,否则抛出

NullPointerException

//map.put(new Student("tom", 86), null);

//map.put(null, "002");

// 3.遍历,Hashtable早期提供的方法较为繁琐Enumeration<Student> keys = map.keys(); while(keys.hasMoreElements()) {

Student key = keys.nextElement(); String value = map.get(key);

System.out.println(key + ": " + value); }

 
}

//运行输出:

Student [name=lucy, age=70]: 019 Student [name=zs, age=78]: 010 Student [name=ww, age=67]: 002 Student [name=rose, age=82]: 005

Hashtable小结:单线程环境下发起利用HashMap,性能更好

 
多线程环境下,发起利用 HashMap + Collections 

​​​​​​​TreeMap

TreeMap是有序映射实现类,它实现了SortedMap接口,基于红黑树数据布局来存储键值对。

TreeMap特点:

键的排序:TreeMap中的键是按照自然序次或自界说比力器举行排序的

 
红黑树实现:TreeMap内部利用红黑树这种自平衡二叉搜索树数据布局来存储键值对

键唯一,值可重复

线程不安全,假如在多线程环境下利用TreeMap,应该利用Collections工具类处置处罚

初始容量:TreeMap没有初始容量的概念,它会根据插入的键值对动态地调解红黑树的巨细

TreeMap小结:

TreeMap底层借助红黑树实现,它提供了高效的有序映射功能,可以用于范围查找、排序和遍历等操纵。但红黑树的平衡操纵会带来额外的开销,相比于HashMap等实现类,TreeMap在插入和删除操纵上大概稍慢。


因此,在选择利用TreeMap时,须要根据详细需求衡量性能和有序性的需求。

​​​​​​​LinkedHashMap

LinkedHashMap是HashMap的一个子类,底层在哈希表的底子上,通过维护一个双向链表来保持键值对的有序性,可以包管存取序次同等。

 底子案例:

创建LinkedHashMap<String, Student>对象,添加元素,观察是否存取序次同等。

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

import com.briup.chap08.bean.Student;

// LinkedHashMap可以包管 存取序次同等

public class Test086_LinkedHashMap {

public static void main(String[] args) {

//1.实例化LinkedHashMap类对象

Map<String, Student> map = new LinkedHashMap<>();

//2.添加元素

map.put("010", new Student("zs", 78)); map.put("005", new Student("rose", 82)); map.put("009", new Student("lucy", 70));

map.put("019", new Student("lucy", 70)); //value可以重复

map.put("002", null);

map.put(null, new Student("ww", 67));

//3.遍历

for (String key : map.keySet()) { System.out.println(key + " " + map.get(key));

}

}

}

//结果输出:

010 Student [name=zs, age=78]

005 Student [name=rose, age=82]

009 Student [name=lucy, age=70]

019 Student [name=lucy, age=70]

002 null

null Student [name=ww, age=67]

 
可以看出,数据存入Map中的序次,就是存储的序次,也是取出的序次!

​​​​​​​Map小结


                       
聚集类

                       
                       
特点

                       
                       
示例

                       
                       

                       

                       
HashMap

                       
                       

                       
基于哈希表实现,无序键值对聚集,键和值均可为null。

                       
                       
Map<String, Integer> map = new HashMap<>();

                       
                       

                       

                       
TreeMap

                       
                       

                       
基于红黑树实现,按键有序排序,键不可为null。

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

                       
                       

                       

                       

                       
LinkedHashMap

                       
                       

                       

                       
基于哈希表和双向链表实现,按插入序次排序,键和值均可为null。

                       
                       
Map<String, Integer> map = new LinkedHashMap<> ();

                       
                       

                       

                       
Hashtable

                       
                       
基于哈希表实现,键值对存储,线程安全,键无序且不允许重复,健和值都不能为null。

                       
                       
Map<String, Integer> map = new Hashtable<>();

                       
Collections

数组工具类是 java.util.Arrays ,可以专门来操纵数组对象,提供静态方法,可直接调用。

聚集工具类是 java.util.Collections ,专门来操纵聚集对象,内里都是静态方法,可以直接调用。

 
注意, Collection 是单列聚集根接口, Collections 是聚集工具类,两者差别!

1) 常用方法:

package java.util;

public class Collections {

// 类外不能实例化对象,工具类重要调用static方法

private Collections() { }

//添补元素值

public static <T> void fill(List<? super T> list, T obj) {

//省略...

}

//获取最大值

public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) {

Iterator<? extends T> i = coll.iterator(); T candidate = i.next();

while (i.hasNext()) {

T next = i.next();

if (next.compareTo(candidate) > 0) candidate = next;

}

return candidate; }

//排序

@SuppressWarnings("unchecked")

public static <T extends Comparable<? super T>> void sort(List<T> list) {

list.sort(null); }


//省略 ... }

 
2)详细方法教学

fill方法,利用指定元素更换指定列表中的全部元素

List<Integer> list = new ArrayList<>(); list.add(1);

list.add(2); list.add(3);

Collections.fill(list, 20);

for(Integer o : list) { System.out.println(o);

}

max方法,根据元素的自然序次,返回给定聚集的最大元素

List<Integer> list = new ArrayList<>(); list.add(1);

list.add(9); list.add(3);

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

min方法,根据元素的自然序次,返回给定聚集的最小元素reverse方法,反转聚会合的元素

List<Integer> list = new ArrayList<>(); list.add(1);

list.add(9); list.add(3);

Collections.reverse(list);

for(Integer o : list) { System.out.println(o);

}

sort方法,根据元素的自然序次,对指定列表按升序举行排序

List<Integer> list = new ArrayList<>(); list.add(1);

list.add(9); list.add(3);

//假如须要,也可以在第二个参数位置传一个比力器对象

//Collections.sort(list,c); Collections.sort(list);

for(Integer o : list) { System.out.println(o);

}shuffle方法,利用默认随机源对指定列表举行置换

List<Integer> list = new ArrayList<>(); list.add(1);

list.add(9); list.add(3);

Collections.shuffle(list);

for(Integer o : list) { System.out.println(o);

}

addAll方法,往聚会合添加一些元素

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

//注意,addAll的第二个参数,是可变参数Collections.addAll(list,1,3,5,7);

for(Integer o : list) { System.out.println(o);

}synchronized相干方法,将非线程安全的聚集转为线程安全(相识,后续多线程再学习)

 
synchronizedCollection,把非线程安全的Collection范例聚集,转为线程安全的聚集

synchronizedList,把非线程安全的List范例聚集,转为线程安全的聚集synchronizedSet,把非线程安全的Set范例聚集,转为线程安全的聚集synchronizedMap,把非线程安全的Map范例聚集,转为线程安全的聚集

案例展示:

 
准备一个聚集,往内里添加元素,然后利用工具类上述方法对其举行操纵,观察结果。

package com.briup.chap08.test;

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

public class Test09_Collections {

public static void main(String[] args) {

//1.准备聚集并添加元素

//List<Integer> list = Arrays.asList(5,3,4,2,2,7); List<Integer> list = new ArrayList<>();

//addAll 往聚会合添加多个元素Collections.addAll(list,5,3,4,2,2,7); System.out.println(list);

//2.max 获取最大值【默认接纳自然排序】Integer max = Collections.max(list); System.out.println("max: " + max);

//3.min 获取聚集最小值

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

//4.reverse 反转Collections.reverse(list); System.out.println(list);

//4.sort 排序【按照 传入的排序算法 举行排序】Comparator<Integer> comp = new Comparator<Integer>() {

@Override

public int compare(Integer o1, Integer o2) {

 
// 逆序

return o2-o1;

 }

};

//注意:排序不会删除聚会合的元素Collections.sort(list,comp); System.out.println("逆序: " + list);

//5.shuffle 随机打乱Collections.shuffle(list); System.out.println("打乱: " + list);

//6.sort 排序【默认自然排序】Collections.sort(list); System.out.println("自然排序: " + list);

//7.fill 添补Collections.fill(list, 20);

System.out.println("after fill: " + list);

//8.将ArrayList【线程不安全】的聚集 转换成  线程安全聚集

//List<Integer> list2 = Collections.synchronizedList(list);

}

}

注意:Collections.sort排序不会删除聚会合的元素。


回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表