Collection 接口的子类型: Set 接口:无序(存进和取出的顺序不同),不可重复,元素没有下标
实现Set接口:HashSet类;SortedSet接口是Set接口的子接口,SortedSet接口的实现类:TreeSet类实现了Set接口;
1. HashSet类
底层采取了哈希表这种数据结构,实际上HashSet集合在new的时候,底层是new了一个HashMap集合,向HashSet集合存储元素,实际上是存储到HashMap集合的key部分了
import java.util.HashSet;
import java.util.Set;
public class Hset {
public static void main(String[] args) {
//创建HashSet集合
Set<String> set =new HashSet<>();
//添加元素
set.add("h4");
set.add("h2");
set.add("h5");
set.add("h1");
set.add("h3");
set.add("h2");
set.add("h3");
//遍历
for(String i :set) {
System.out.println(i);
}
}
//结果:
// h1
// h2
// h3
// h4
// h5
}
/*1. 存储顺序和取出顺序不同,不可重复
*2. 看一下源码:
* public HashSet() {
map = new HashMap<>();
}
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
就是:向HashSet集合存储元素,实际上是存储到HashMap集合的key部分了
* */
2.TreeSet类(元素可以自动排序,序指大小)
SortedSet接口:由于继承了Set接口,其特点有无序不可重复,没有下标,但放在SortedSet集合中的元素可以自动排序,我们成为可排序集合
SortedSet接口的实现类的TreeSet类:底层采取了二叉树这种数据结构,实际上TreeSet集合在new的时候,底层是new了一个TreeMap集合,向TreeSet集合存储元素,实际上是存储到TreeMap集合中了
import java.util.Set;
import java.util.TreeSet;
public class Tset {
public static void main(String[] args) {
//创建TreeSet集合
Set<String> set =new TreeSet<>();
//添加元素
set.add("a");
set.add("b");
set.add("g");
set.add("r");
set.add("d");
set.add("d");
set.add("d");
//遍历
for(String i :set) {
System.out.println(i);
}
}
//结果:
//a
//b
//d
//g
//r
}
/*
* 1.从小到大排序*/
*/
Map接口 (以key和value的这种键值对存储元素)
- Map接口和Collection 接口没有关系,Map集合以key和value的这种键值对的方式存储元素,key和value都是存储java对象的内存地址,所有Map集合的key都是无序不可重复的,就是说Map集合的key和Set集合存储元素的特点相同,Map集合的key,就是一个Set集合,往Set集合中放数据,实际上放到Map集合的key部分
- **Map接口支持泛型: Map<K,V> **
1.Map接口中常用的方法
**
V put(K key, V value) 向 Map中添加键值对
V get( Object key ) 通过key获取value
void clear() 清空Map集合
boolean containsKey( Object key ) 判断Map中是否包含某个key
boolean containsValue( Object value ) 判断Map中是否包含某个 value
V remove( Object key ) 通过key删除键值对
int size() 获取键值对的数量
Collection<V>
values() 获取Map集合中的所有的value ,返回一个Collection集合
boolean isEmpty( ) 判断Map集合中元素的个数是否为0**
package 集合练习;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
public class Map1 {
public static void main(String[] args) {
//创建Map集合对象,对于Map<K, V> 可以通过泛型分别来统一Map集合中 key 和 value 的类型
Map<Integer, String> map = new HashMap<>();
//1. 向Map集合中添加键值对 V put(K key, V value)
map.put(1, "diyi");//1是自动装箱
map.put(2, "dier");
map.put(3, "disan");
map.put(4, "disi");
//2. 通过key获取value V get(Object key)
String string =map.get(2);
System.out.println(string);
//3. 获取键值对的数量 int size()
System.out.println("键值对的数量:"+map.size());
//4. 通过key删除键值对 V remove(Object key)
map.remove(4);
System.out.println("此时键值对的数量:"+map.size());
//5.判断Map中是否包含某个key boolean containsKey( Object key)
System.out.println(map.containsKey(4));
//6.判断Map中是否包含某个value boolean containsValue( Object value )
System.out.println(map.containsValue("diyi"));
//强调:contains方法底层调用的都是equals方法,所以自定义的类要重写equals方法。
System.out.println(map.containsValue(new String("diyi")));
//7.获取Map集合中的所有的value ,返回一个Collection Collection<V> values();
Collection<String> values = map.values();
for(String s:values) {
System.out.println(s);
}
//8. 清空Map集合 void clear()
map.clear();
System.out.println(map.size());
}
/*
* 结果:
dier
键值对的数量:4
此时键值对的数量:3
false
true
true
diyi
dier
disan
0
*/
}
2.Map集合遍历常用的方法
1.第一种,获取所有的key ,存放在Set集合中,通过遍历key, 来遍历value
package 集合练习;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class Map2 {
public static void main(String[] args) {
//创建Map集合对象
Map<Integer, String> map = new HashMap<>();
//向Map集合中添加键值对
map.put(1, "diyi");//1是自动装箱
map.put(2, "dier");
map.put(3, "disan");
map.put(4, "disi");
//遍历Map集合
//1.先获取所有的key,所有的key是一个set集合 此处调用keySet方法,返回Set集合 Set<K> keySet() 其中K代表key的类型
Set<Integer> keys = map.keySet();
//2.遍历key ,通过key获取value,其中遍历Set集合方法可以是迭代器,foreach
//(1)迭代器
Iterator<Integer> it = keys.iterator();
while(it.hasNext()) {
Integer key = it.next();
String value = map.get(key);
System.out.println(key+"="+value);
}
//(2)foreach方法
for(Integer key:keys) {
System.out.println(key+"="+map.get(key));
}
/*
1=diyi
2=dier
3=disan
4=disi
1=diyi
2=dier
3=disan
4=disi
*/
}
}
第二种:把Map集合直接全部转换为Set集合 Set<Map.Entry<K, V>> entrySet() ,Set集合 中的元素类型是Map.Entry ,和String类型一样,只不过Map.Entry是静态内部类,Map下的静态内部类
/* Set<Map.Entry<K, V>> entrySet() 返回Set集合,其中每个对象都是Map.Entry<Integer,String>类型
* 每个对象Node包含两个属性:Integer key属性, String value属性
就是将每个Map键值对,转换为Set集合中的一个一个对象Node*/
Set<Map.Entry<Integer,String>> set = map.entrySet();
//遍历Set集合,每一次取出一个Node
//(1)迭代器
Iterator<Map.Entry<Integer,String>> iterator2 = set.iterator();
while(iterator2.hasNext()) {
Map.Entry<Integer,String> node = iterator2.next();
Integer key =node.getKey();
String value = node.getValue();
System.out.println(key+"="+value);
}
/*源码:
* interface Entry<K, V> {
* K getKey();
* V getValue();
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
V value;
Node<K,V> next;
* }*/
//(2)foreach方法
for(Map.Entry<Integer,String> node:set) {
System.out.println(node.getKey() + "=" + node.getValue());
}
/*
1=diyi
2=dier
3=disan
4=disi
1=diyi
2=dier
3=disan
4=disi
*/
}
分析以上两种,第二种效率更高,因为获取key和value都直接从node对象中获取的属性值,当数据量较大,可以优先选择
静态内部类(了解一下)
public class ZongClass {
public static void main(String[] args) {
//类名调用内部类静态方法,注意:类名指ZongClass.InnerClass
ZongClass.InnerClass.m1();
//创建内部类对象调用静态内部类的实例方法
ZongClass.InnerClass mClass = new ZongClass.InnerClass();
mClass.m2();
}
//声明一个静态内部类
static class InnerClass{
public static void m1() {
System.out.println("静态内部类的静态方法m1执行");
}
public void m2() {
System.out.println("静态内部类的实例方法m2执行");
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现