set接口
set:一个不包含重复元素的Collection,存储顺序和取出顺序不一致(每一次测试可能都不相同)
1.HashSet
HashSet:不保证set的迭代顺序;特别是不保证该顺序恒久不变
HashSet()方法存储字符串的时候,字符串内容相同的只存储了一个的原因:
步骤:
- 首先比较哈希值
- 如果相同,继续走,比较地址值或者走equals()
- 如果不同,就直接添加到集合中
如果类没有重写这两个方法,默认使用的Object()。
而String类重写了hashCode()和equals()方法(保证了唯一性),所以,他就可以把内容相同的字符串去掉,只留下一个。
LinkedHashSet()底层数据结构由哈希表和链表组成,哈希表保证元素的唯一性,链表保证元素有序
2. TreeSet
底层数据结构是红黑树
能够对元素按照某种规则进行排序,具体取决于使用的构造方法
(1)自然排序(无参构造)
(2)使用创建set时提供的Comparator进行排序
TreeSet存储自定义对象并遍历(重点在于重写Comparable接口)
package cn.itcast_01;
import java.util.TreeSet;
//要告诉怎么排序:自然排序,按照年龄从打到小
//要告诉元素什么情况下为相等:成员变量值都相同即为一个元素
public class TreeDemo {
public static void main(String[] args) {
TreeSet<Student> ts = new TreeSet<>();
Student s1 = new Student("王力宏",23);
Student s2 = new Student("林青霞",38);
Student s3 = new Student("王力宏",35);
Student s4 = new Student("胡歌",38);
Student s5 = new Student("王力宏",23);
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
for(Student s : ts) {
System.out.println(s.getName()+"----"+s.getAge());
}
}
}
public class Student implements Comparable<Student> {
private String name;
private int age;
/*
*省略中间的步骤
*/
@Override
public int compareTo(Student s) {
//主要条件:按照年龄排序
int num = this.age - s.age;
//次要条件:年龄相同时,还要去看姓名是否也相同
int num2 = num == 0 ? this.name.compareTo(s.name):num;
return num2;
}
}
有限按照姓名长度进行排序(且采用了匿名对象的方式)
public class TreeDemo {
public static void main(String[] args) {
//如果一个方法的参数是接口,那么真正要的是接口的实现类对象
//而匿名内部类就可以实现这个东西
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
//姓名长度
int num = s1.getName().length() - s2.getName().length();
//姓名内容
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
//年龄
int num3 = num == 0 ? s1.getAge() - s2.getAge() : num2;
return num3;
}
});
Student s1 = new Student("wanglihong",23);
Student s2 = new Student("linqingxia",38);
Student s3 = new Student("wanglihong",35);
Student s4 = new Student("huge",38);
Student s5 = new Student("wanglihong",23);
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
for(Student s : ts) {
System.out.println(s.getName()+"----"+s.getAge());
}
}
}
TreeSet集合保证元素排序和唯一性的原理:
(1)唯一性:根据比价返回是否为0来决定
(2)排序:
- 自然排序(元素具备比较性):让元素所属的类实现自然排序接口 Comparable
- 比较器排序(集合具备比较性):让集合的构造方法接收一个比较器接口的子类对象 Comparator
产生10个1—20间的随机数且不能重复
import java.util.HashSet;
import java.util.Random;
public class HashSetDemo {
public static void main(String[] args) {
Random r = new Random();
HashSet<Integer> ts = new HashSet<Integer>();
while(ts.size() < 10) {
int num = r.nextInt(20) + 1;
ts.add(num);
}
for (Integer i : ts) {
System.out.println(i);
}
}
}
Map集合
特点:将键映射到值的对象;一个映射不能包含重复的键;每个键只能映射到一个键
Map集合和Collection集合的区别:
(1)Map集合存储元素是成对出现的,Map集合的键是唯一的,值是可重复的,数据结构值针对键有效,跟值无关
(2)Collection集合存储元素是单独出现的,Collection的儿子Set是唯一的,数据结构针对元素有效
Map集合的功能概述:
- 添加功能:V put(K key, V value):添加元素
另一个功能:如果键是第一次存储,就直接存储元素,返回null;如果键不是第一次存在,就用值把以前的值替 换掉,返回以前的值 - 删除功能:void clear():移除所有的键值元素
V remove (Object key):根据键删除键值对元素,并把值返回 - 判断功能:boolean containsKey(Object key):判断集合是否包含指定的键
boolean containsValue(Object value):判断集合是否包含指定的值
boolean isEmpty():判断集合是否为空 - 获取功能:Set<Map.Entry<K,V>> entrySet():返回键值对对象的集合
V get(Object key):根据键获取值
Set<K> keySet():获取集合中所有键的集合
Collection<V> values():获取集合中所有值的集合 - 长度功能:int size():返回集合中的键值对的个数
遍历键值对的键和值
Map的遍历分为两种方式:(增强for是Set的遍历方式,所以可以通过将Map转换成Set然后进行增强for的遍历)
- 根据键找值
- 根据键值对对象分别找键和值
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class MapDemo1 {
public static void main(String[] args) {
Map<String, String> map = new HashMap<String,String>();
map.put("杨过", "小龙女");
map.put("郭靖", "黄蓉");
map.put("杨康", "穆念慈");
map.put("陈玄风", "梅超风");
//方法1
//获取所有键值对对象的集合
Set<Map.Entry<String, String>> set = map.entrySet();
//遍历键值对对象的集合,得到每一个键值对对象
for (Map.Entry<String, String> me : set) {
//根据键值对对象获取键和值
System.out.println(me.getKey()+"----"+me.getValue());
}
//方法2
Set<String> set = map.keySet();
for(String key : set) {
String value = map.get(key);
System.out.println(key+"----"+value);
}
}
}
HashMap:键是哈希表结构,可以保证键的唯一性
LinkedHashMap:是Map接口的哈希表和连接列表的实现,键是有序的
TreeMap:是基于红黑树的Map接口的实现
Map集合嵌套
HashMap和Hashtable的区别:
(1)Hashtable:线程安全,效率低,不允许null键和null值
(2)HashMap:线程不安全,效率高,允许null键和null值