TreeSet
特点: 无序的,不可重复
底层结构:红黑树进行存储
TreeSet特点:有序(自动从小到大升序排序)
public class TreeSet02 {
public static void main(String[] args) {
TreeSet tree=new TreeSet();
tree.add("abc");
tree.add("ab");
tree.add("c");
tree.add("ac");
tree.add("bc");
System.out.println(tree);
//输出结果 [ab, abc, ac, bc, c]
可以定义比较规则,排序规则,并且可以使用去重原则
比较器有内部比较器和外部比较器
内部比较器是自然排序:实现Comparable接口.重写comparaTo方法,在方法中定义比较规则,默认的比较规则
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSet02 {
public static void main(String[] args) {
// TreeSet set=new TreeSet(); 默认调用内部比较器,如果没有定义抛出异常
/*
Person 类实现了Comparable接口,重写了comparaTo方法,重新定义了比较规则
@Override
public int compareTo(Person o) {
//return o.age-this.age; 按年龄降序排序
return this.age-o.age; 按年龄升序排序
}
*/
TreeSet set=new TreeSet();
set.add(new Person("胡歌",35));
set.add(new Person("杨洋",30));
set.add(new Person("彭于晏",34));
System.out.println(set);
//运行结果
/* [Person [name=杨洋, age=30], Person [name=彭于晏, age=34], Person [name=胡歌, age=35]]*/
}
}
外部比较器是指定一个规则进行排序:实现一个Comparator接口,重写compare()方法,方法内部定义比较规则
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSet02 {
public static void main(String[] args) {
// TreeSet set=new TreeSet(new Demo()); //调用参数实现类对象的compare()方法
/*TreeSet set=new TreeSet(new Comparator<Person>(){
@Override
public int compare(Person o1, Person o2) {
return o1.getAge()-o2.getAge();
}
});*/
Comparator com=(o1,o2)->((Person)o1).getAge()-((Person)o2).getAge();
//实现接口的匿名内部类,使用lambda表达式简写,外部比较器,按年龄降序排序
TreeSet set=new TreeSet((o1,o2)->((Person)o2).getAge()-((Person)o1).getAge());
set.add(new Person("胡歌",35));
set.add(new Person("杨洋",30));
set.add(new Person("彭于晏",34));
System.out.println(set);
//运行结果
/* [Person [name=胡歌, age=35], Person [name=彭于晏, age=34], Person [name=杨洋, age=30]]*/
}
}
注意:如果在外部定义了比较器,那么无论 引用数据类型是否实现了Comparable接口,都是按外部比较器定义的规则进行排序
Map接口
- Map:存储的每一个数据都是一个键值对形式存在的 k,v
- key: 无序的,唯一的 —>就是一个set集合
- value:无序的,可重复的
- 一个key对象一个value,两者之间存在映射关系
- 如果存储数据的时候,key相同,value的值会被覆盖
- map中,HashMap的去重,根据Map的key进行计算
- TreeMapd 的去重+排序,是根据Map的key进行计算
- 如果一个key,想要对多个value值,可以把多个value存在一个容器中
Map接口中常用的方法
方法 | 说明 |
---|---|
Object put(Object key,Object vaule) | 存放键值对 |
Object get(Object key) | 通过键对象查找得到值对象 |
Object remove(Object key) | 删除键对象对应的键值对 |
boolean containsKey(Object key) | Map容器中是否包含键对象对应的键值对 |
boolean containsValue(Object value) | Map容器中是否包含值对象对应的键值对 |
int size() | 包含键值对的数量 |
boolean isEmpty() | Map是否为空 |
void putAll(Map t) | 将t的所有键值对存放到本Map对象 |
void clear() | 清空Map对象的所有键值对 |
import java.util.HashMap;
import java.util.Map;
public class MapDemo01 {
public static void main(String[] args) {
Map<Integer,String> map=new HashMap();
//Object put(Object key,Object vaule)
//存放键值对
map.put(01, "唐三");
map.put(02, "奥斯卡");
map.put(03, "戴沐白");
map.put(04, "小舞");
map.put(04, "宁荣荣");
//key值相等直接覆盖"小舞"
System.out.println(map);
//输出结果 {1=唐三, 2=奥斯卡, 3=戴沐白, 4=宁荣荣}
//Map容器中是否包含键对象对应的键值对
System.out.println(map.containsKey(03));
//输出结果 true
//Map容器中是否包含值对象对应的键值对
System.out.println(map.containsValue("小舞"));
//输出结果 false
// V get(Object key) 通过键对象查找得到值对象
System.out.println(map.get(02));
//输出结果 奥斯卡
// V remove(Object key) 删除键对象对应的键值对
System.out.println(map.remove(04));
//输出结果 宁荣荣 返回删除的对象
System.out.println(map);
//输出结果 {1=唐三, 2=奥斯卡, 3=戴沐白}
//获取容器中元素的个数
System.out.println(map.size());
//输出结果 3
}
}
Map的遍历方式
- 获取所有的key,根据key拿value keySet()
- 获取所有的value,values()这种遍历方式无法获取key,只能遍历所有的value
- entrySet()获取所有的键值对,每个键值对都是一个Map.ENTRY类型的数据放在一个set集合中
import java.util.Collection;
public class MapDemo{
public static void main(String[]args){
HashMap<Stirng,Double> map=new HashMap();
map.put("唐粒洋",10000.00);
map.put("王宇晨",5000.00);
map.put("韩冲",12000.00);
System.out.println(map);
//输出结果 {王宇晨=5000.0, 唐粒洋=10000.0, 韩冲=12000.0}
System.out.println("------keyset()------");
Set<String> keys=map.keySet();
//遍历set,for...each 和迭代器
for(String s:keys){
System.out.pringln(s+"-->"+map.get(s));
}
/*
运行结果:
王宇晨-->5000.0
唐粒洋-->10000.0
韩冲-->12000.0
*/
System.out.println("------entrySet()------");
Set<Map.Entry<String,Double>> set= map.entrySet();
//遍历set获取到每一个Map.Entry类型的数据其实就是每一个键值对,可以根据Map.Entry的方法获取每一个键值对的key和value
for(Map.Entry<String,Double> m:set){
System.out.println(m.getKey()+"-->"+m.getVaule());
}
/*
运行结果:
王宇晨-->5000.0
唐粒洋-->10000.0
韩冲-->12000.0
*/
}
}
Collections操作容器的工具类
常用方法:
- void sort(List) //对 List 容器内的元素排序,按照升序进行排序。
- void shuffle(List) //对 List 容器内的元素进行随机排列
- void fill(List, Object) //用一个特定的对象重写整个 List 容器
- int binarySearch(List, Object)//采用折半查找的方法查找特定对象
如何解决HashMap线程不安全的问题:
- 使用Hashtable容器
- static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) 使用Collecitons工具类中的synchronizedMap,返回一个线程安全的map
- juc包下的ConcurrentHashMap<K,V>类 —推荐使用