目录
Set集合:
Set:
一个不包含重复元素的Collection
HashSet:
不保证Set的迭代顺序;特别 是它不保证该顺序恒久不变
因Set是一个接口,所以要用实现类HashSet来实现实例化(多态)
import java.util.HashSet;
import java.util.Set;
public class SetDemo {
public static void main(String[] args) {
Set<String>set = new HashSet<String>();
set.add("hello");
set.add("world");
set.add("java");
//测试唯一性
set.add("hello");
for (String s :set){
System.out.println(s);
}
}
}
输出结果:
world
java
hello可知未保证存储和取出的顺序一致
HashSet保证元素唯一性的原理:
通过访问add方法的源码,可以看到添加功能的执行过程中,是进行了数据的判断的。
判断流程为:
首先比较对象的哈希值是否相同,这个哈希值是根据对象的hashCode()计算出来的
如果哈希值不同,就直接添加到集合中
如果哈希值相同,就继续执行equals()进行比较,
返回 的是true的话,说明元素重复,不添加
返回的是false的话,说明元素不重复,就添加
如果我们使用HashSet集合存储对象,要想保住元素的唯一性,就必须重写hashCode()和equals()方法。
HashSet集合练习:
需求:HashSet存储自定义变量并遍历
下第一段代码Student类如下相同
public class Student {
private String name;
private int age;
public Student(){}
public Student(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;
}
}
import java.util.HashSet;
import java.util.Iterator;
public class HashSetTest {
public static void main(String[] args) {
//创建集合对象
HashSet<Student>hs = new HashSet<Student>();
Student s1 = new Student("林青霞",30);
Student s2 = new Student("王祖贤",31);
Student s3 = new Student("张曼玉",33);
hs.add(s1);
hs.add(s2);
hs.add(s3);
//遍历
for (Student s :hs){
System.out.println(s.getName()+"---"+s.getAge());
}
System.out.println("-------");
Iterator<Student>it = hs.iterator();
while (it.hasNext()){
Student s = it.next();
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
输出结果:
张曼玉---33
王祖贤---31
林青霞---30
-------
张曼玉---33
王祖贤---31
林青霞---30
需求:需保证元素唯一性:
因存储元素所属的类未重写hashCode()和equals()方法,所以保证不了元素唯一性
所以Student类改为了如下:
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student(){}
public Student(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 boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
可发现重写了hashCode方法和equals方法
Map集合:
Map:
将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值
如:学生的学号和姓名
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
Map<String,String>map = new HashMap<String, String>();
//添加元素
map.put("it001","王祖贤");
map.put("it002","林青霞");
map.put("it003","张曼玉");
System.out.println(map);
}
}
输出结果:
{it003=张曼玉, it002=林青霞, it001=王祖贤}
表明HashMap重写了toString的方法
Map集合的成员方法:
V put(K key,V value):添加元素
V remove(Object key):根据键删除键值对元素
void clear():移除所有的键值对元素
boolean containsKey(Object key):判断集合是否包含指定的键
boolean containsValue(Object value):判断集合是否包含指定的值
boolean isEmpty():判断集合是否为空
int size():返回集合中的键值对的对数
此处演示前3种,后几种运用类似,调用对象,引用方法即可,前表示返回值类型(注意V表示返回键值)
Map集合中的实现类的数据结构只针对键有效
V put(K key,V value):添加元素
如果键是第一次存储,就直接存储元素,返回null
如果键不是第一次存储,就用值把以前的值替换,返回以前的值
import java.util.HashMap;
import java.util.Map;
public class Test001 {
public static void main(String[] args) {
Map<String,String>map = new HashMap<String, String>();
System.out.println("put:"+map.put("张无忌","赵敏"));
System.out.println("put:"+map.put("张无忌","周芷若"));
}
}
输出结果:
put:null
put:赵敏
V remove(Object key):根据键删除键值对元素
import java.util.HashMap;
import java.util.Map;
public class Test001 {
public static void main(String[] args) {
Map<String,String>map = new HashMap<String, String>();
map.put("张无忌","赵敏");
map.put("郭靖","黄蓉");
System.out.println(map.remove("郭靖"));
}
}
输出结果:
黄蓉
void clear():移除所有的键值对元素
import java.util.HashMap;
import java.util.Map;
public class Test001 {
public static void main(String[] args) {
Map<String,String>map = new HashMap<String, String>();
map.put("张无忌","赵敏");
map.put("郭靖","黄蓉");
map.clear();
System.out.println(map);
}
}
输出结果:
{}
Map集合的获取功能测试:
V get(Object key):根据键获取值
Set<K> keySet():获取所有键的集合
Collection<V> values():获取所有值的集合
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test001 {
public static void main(String[] args) {
Map<String,String>map = new HashMap<String, String>();
map.put("张无忌 ","赵敏 ");
map.put("郭靖 ","黄蓉 ");
map.put("杨过 ","小龙女 ");
System.out.println(map.get("张无忌 "));
System.out.println(map.get("张三丰 "));
System.out.println("------");
Set<String>set = map.keySet();
for (String key:set){
System.out.print(key);
}
System.out.println("");
Collection<String>values = map.values();
for (String value : values){
System.out.print(value);
}
}
}
输出结果:
赵敏
null
------
张无忌 杨过 郭靖
赵敏 小龙女 黄蓉
Map集合的遍历:
Map集合为双链集合
方式1:
思路:
A:获取所有键的集合
B:遍历键的集合,获取到每一个键
C:根据键去找值
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test001 {
public static void main(String[] args) {
Map<String,String>map = new HashMap<String, String>();
map.put("张无忌 ","赵敏 ");
map.put("郭靖 ","黄蓉 ");
map.put("杨过 ","小龙女 ");
Set<String>set = map.keySet();
for (String key:set){
String value = map.get(key);
System.out.println(key+"---"+value);
}
}
}
输出结果:
张无忌 ---赵敏
杨过 ---小龙女
郭靖 ---黄蓉
方式2:
思路:
A:获取所有键值对对象的集合
B:遍历键值对对象的集合,得到每一个键值对对象
C:根据键值对对象获取键和值
通过Set<Map.Entry<K,V>>entrySet()
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test001 {
public static void main(String[] args) {
Map<String,String>map = new HashMap<String, String>();
map.put("张无忌 ","赵敏 ");
map.put("郭靖 ","黄蓉 ");
map.put("杨过 ","小龙女 ");
Set<Map.Entry<String,String>>set = map.entrySet();
for (Map.Entry<String,String>me:set){
String key = me.getKey();
String value = me.getValue();
System.out.println(key+"---"+value);
}
}
}
输出结果:
张无忌 ---赵敏
杨过 ---小龙女
郭靖 ---黄蓉
Map集合的两种遍历方式的图解:
HashMap集合的练习:
两种遍历方法遍历学生类
HashMap<String,Student>
键:String学号
值:Student学生对象
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class test0011 {
public static void main(String[] args) {
HashMap<String,Student>hm = new HashMap<String, Student>();
Student s1 = new Student("林青霞",30);
Student s2 = new Student("王祖贤",31);
Student s3 = new Student("张曼玉",33);
hm.put("it001",s1);
hm.put("it002",s2);
hm.put("it003",s3);
Set<String>set = hm.keySet();
for (String key :set){
Student value = hm.get(key);
System.out.println(key+"---"+value.getName()+"---"+value.getAge());
}
System.out.println("--------");
Set<Map.Entry<String,Student>>set2 = hm.entrySet();
for (Map.Entry<String,Student> me:set2){
System.out.println(me.getKey()+"---"+me.getValue().getName()+"---"+me.getValue().getAge());
}
}
}
练习2:任选一种方式遍历
HashMap<Student,String>
键:Student 学生对象
值:String 学生住址
要求:如果学生对象的成员变量值相同,就说明是同一个键。
注意:Student类要重写了HashCode和equals方法
import java.util.HashMap;
import java.util.Set;
public class test0011 {
public static void main(String[] args) {
HashMap<Student,String>hm = new HashMap<Student, String>();
Student s1 = new Student("林青霞",30);
Student s2 = new Student("王祖贤",31);
Student s3 = new Student("张曼玉",33);
Student s4 = new Student("张曼玉",33);
hm.put(s1,"北京");
hm.put(s2,"上海");
hm.put(s3,"广州");
hm.put(s3,"香港");
Set<Student>set = hm.keySet();
for (Student key :set){
String value = hm.get(key);
System.out.println(key.getName()+"---"+key.getAge()+"---"+value);
}
}
}
输出结果:
王祖贤---31---上海
张曼玉---33---香港
林青霞---30---北京
集合的嵌套练习:
需求:ArrayList集合嵌套HashMap集合并遍历。
定义一个ArrayList集合,它包含三个元素,每一个元素都是HashMap类型的。
每一个HashMap集合的键和值都是String类型的,
键:String 丈夫的姓名
值:String 妻子的姓名
给出如下的字符串数据,请用代码实现需求。
第一个HashMap集合的元素:
孙策 大乔
周瑜 小乔
第二个HashMap集合的元素:
郭靖 黄蓉
杨过 小龙女
第三个HashMap集合的元素:
令狐冲 任盈盈
林平之 岳灵珊
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
public class Together {
public static void main(String[] args) {
ArrayList<HashMap<String,String>>array = new ArrayList<HashMap<String,String>>();
//创建元素
HashMap<String,String>hm = new HashMap<String, String>();
hm.put("孙策","大乔");
hm.put("周瑜","小乔");
array.add(hm);
HashMap<String,String>hm1 = new HashMap<String, String>();
hm1.put("郭靖","黄蓉");
hm1.put("杨过","小龙女");
array.add(hm1);
HashMap<String,String>hm2 = new HashMap<String, String>();
hm2.put("令狐冲","任盈盈");
hm2.put("林平之","岳灵珊");
array.add(hm2);
for (HashMap<String,String>hm4:array){
Set<String>set = hm4.keySet();
for (String key:set){
String values = hm4.get(key);
System.out.println(key+"---"+values);
}
}
}
}
输出结果:
孙策---大乔
周瑜---小乔
杨过---小龙女
郭靖---黄蓉
令狐冲---任盈盈
林平之---岳灵珊
需求:HashMap集合嵌套ArrayList集合并遍历。
定义一个HashMap集合,它包含三个元素,每一个元素的键是String类型,值是ArrayList类型。
键:String 人物来自哪部电视剧
值:ArrayList 人物的名称
每一个ArrayList集合的数据是String类型的。
给出如下的字符串数据,请用代码实现需求。
第一个ArrayList集合的元素:(三国演义)
诸葛亮
赵云
第二个ArrayList集合的元素:(西游记)
唐僧
孙悟空
第三个ArrayList集合的元素:(水浒传)
武松
鲁智深
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
public class Test {
public static void main(String[] args) {
HashMap<String, ArrayList<String>>hm = new HashMap<String, ArrayList<String>>();
ArrayList<String>array1 = new ArrayList<String>();
array1.add("诸葛亮");
array1.add("赵云");
ArrayList<String>array2 = new ArrayList<String>();
array2.add("唐僧");
array2.add("孙悟空");
ArrayList<String>array3 = new ArrayList<String>();
array3.add("武松");
array3.add("鲁智深");
hm.put("三国演义",array1);
hm.put("西游记",array2);
hm.put("水浒传",array3);
Set<String> set = hm.keySet();
for (String key:set){
System.out.println(key);
ArrayList<String> value = hm.get(key);
for (String s:value){
System.out.println("\t"+s);
}
System.out.println("-----------");
}
}
}
输出结果:
水浒传
武松
鲁智深
-----------
三国演义
诸葛亮
赵云
-----------
西游记
唐僧
孙悟空
-----------