一、Set 接口及其实现类
Set 接口不能存储重复元素
1、HashSet 类
- 元素是无序的(既不是添加顺序,也不是按元素的自然顺序)
代码示例如下:
import java.util.HashSet;
public class HashSetDemo1 {
public static void main(String[] args) {
/*
Set 接口 不能存储重复元素
HashSet
元素是无序的(既不是添加顺序,也不是按元素的自然顺序)
*/
HashSet<String> set = new HashSet<>();
set.add("x");
set.add("a");
set.add("h");
set.add("b");
set.add("b");
// set.clear();
System.out.println(set.contains("a"));
System.out.println(set.isEmpty());
System.out.println(set.remove("b"));
System.out.println(set.size());
System.out.println(set);
}
}
思考:向Hashset中添加元素时,是如何判断元素是否重复的
解答:添加元素时 调用equals()判断, 效率低(一个一个字符判断),其底层用到hashCode() 和 equals() 方法。例如:元素:asdfghjkl 用内容计算一个hash值(整数),用hash值比较速度快,但是hash是不安全,有可能内容不同,计算的hash值相同,当hash相同时,调用equals()判断内容是否相等这样既效率提高了 也保证安全
代码示例如下:
import java.util.HashSet;
public class HashSetDemo2 {
public static void main(String[] args) {
/*
Set 接口 不能存储重复元素
HashSet
元素是无序的(既不是添加顺序,也不是按元素的自然顺序)
向Hashset中添加元素时,是如何判断元素是否重复的
添加元素时 调用equals()判断, 效率低(一个一个字符判断)
底层用到hashCode() 和 equals() 方法
xsadasdsadsasa 用内容计算一个hash值(整数),用hash值比较速度快
但是hash是不安全,有可能内容不同,计算的hash值相同,
当hash相同时,调用equals()判断内容是否相等
这样既效率提高了 也保证安全
*/
HashSet<String> set = new HashSet<>();
set.add(new String("xsadasdsadsasa"));//500
set.add("a");
set.add("通话");
set.add("重地");
set.add(new String("xsadasdsadsasa"));//500
System.out.println(set);
}
}
import java.util.HashSet;
public class HashSetDemo3 {
public static void main(String[] args) {
/*
Set 接口 不能存储重复元素
HashSet
元素是无序的(既不是添加顺序,也不是按元素的自然顺序)
向Hashset中添加元素时,是如何判断元素是否重复的
添加元素时 调用equals()判断, 效率低(一个一个字符判断)
底层用到hashCode() 和 equals() 方法
xsadasdsadsasa 用内容计算一个hash值(整数),用hash值比较速度快
但是hash是不安全,有可能内容不同,计算的hash值相同,
当hash相同时,调用equals()判断内容是否相等
这样既效率提高了 也保证安全
*/
HashSet<Student> set = new HashSet<>();
Student student1 = new Student(101,"张三");
Student student2 = new Student(102,"李四");
Student student3 = new Student(103,"王五");
Student student4 = new Student(101,"张三");
/*
添加时,判断会调用类中hashCode()计算hash值, 类中,没有hashCode(),会调用父类中的hashCode()
Object类中的 public native int hashCode(); native本地方法(操作系统提供的)
所以只要是new出来的,调用Object类中hash值,是内存地址,肯定不相同
如果我们想要对象中的内容相等就判定为重复元素,就必须在我们的类中重写hashCOde() equals() 用对象中的内容来计算hash值
*/
set.add(student1);
set.add(student2);
set.add(student3);
set.add(student4);
System.out.println(set);//
}
}
public class Student extends Object implements Comparable<Student>{
private int num;
private String name;
public Student(int num, String name) {
this.num = num;
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
if (num != student.num) return false;
return name.equals(student.name);
}
@Override
public int hashCode() {
int result = num;
result = 31 * result + name.hashCode();
return result;
}
@Override
public String toString() {
return "Student{" +
"num=" + num +
", name='" + name + '\'' +
'}';
}
/*
提供的排序比较的方法
*/
@Override
public int compareTo(Student o) {
return this.num - o.num;
}
}
2、TreeSet 类
- TreeSet 底层是树型结构
- 添加进来的元素可以排序 (有序的 不是添加的顺序,是元素的自然顺序)
代码示例如下:
import java.util.TreeSet;
public class TreeSetDemo1 {
/*
Set 不能存储重复元素
TreeSet
底层是树型结构
添加进来的元素可以排序 (有序的 不是添加的顺序,是元素的自然顺序)
*/
public static void main(String[] args) {
TreeSet<Integer> set = new TreeSet<>();
set.add(3);
set.add(4);
set.add(1);
set.add(2);
set.add(3);
//set.clear();
//set.size();
//set.contains(1);
System.out.println(set.first());//删除并返回第一个元素
set.isEmpty();
set.remove(1);//删除指定内容的元素
System.out.println(set.pollLast());//删除并返回最后一个元素
System.out.println(set);
}
}
注:底层是树形结构 有一个根节点, 每一个节点有两个子节点, 大的元素向右放,小的元素向左放
代码示例如下:
import java.util.TreeSet;
public class TreeSetDemo2 {
/*
Set 不能存储重复元素
TreeSet
底层是树形结构 有一个根节点, 每一个节点有两个子节点, 大的元素向右放,小的元素向左放
添加进来的元素可以排序 (有序的 不是添加的顺序,是元素的自然顺序)
*/
public static void main(String[] args) {
TreeSet<Student> set = new TreeSet<>();
Student student1 = new Student(101,"张三");
Student student2 = new Student(102,"李四");
Student student3 = new Student(103,"王五");
Student student4 = new Student(101,"张三");
set.add(student2);
set.add(student4);
set.add(student3);
set.add(student1);
System.out.println(set);
}
}
二、Map 接口
-
本质是一组键值对
- 键不能重复,值可以重复
- 一个键映射到一个值
HashMap —— 键是无序的
代码示例如下:
import java.util.Collection;
import java.util.HashMap;
import java.util.Set;
public class HashMapDemo1 {
/*
Map
键 值对
键不能重复,值可以重复
一个键映射到一个值
HashMap
键是无序的
*/
public static void main(String[] args) {
HashMap<String,String> map = new HashMap<>();
map.put("c", "cc");
map.put("x", "xx");
map.put("a", "xx");
map.put("h", "hh");
map.put("c", "CC");
System.out.println(map.get("x"));//通过key获取到key对应的value
//map.clear(); 删除所有的键值映射
//System.out.println(map.remove("x"));删除键值映射,并返回改键对应的值
System.out.println(map.containsKey("x")); //判断键是否存在
System.out.println(map.containsValue("hh"));//判断值是否存在
System.out.println(map.isEmpty());//判断是否是空的
System.out.println(map.size());
Collection<String> values = map.values();
System.out.println(values);
Set<String> keys = map.keySet();
System.out.println(keys);
System.out.println(map);
}
}
import java.util.Collection;
import java.util.HashMap;
import java.util.Set;
public class HashMapDemo2 {
/*
Map
键 值对
键不能重复,值可以重复
一个键映射到一个值
HashMap
键是无序的
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
*/
public static void main(String[] args) {
HashMap<String,String> map = new HashMap<>();
map.put("c", "cc");
map.put("x", "xx");
map.put("a", "xx");
map.put("h", "hh");
map.put("c", "CC");
}
}