一,TreeSet
1.1 TreeSet的用法
TreeSet是无序,不可重集合
底层结构: 红黑树(平衡二叉树)
特点: 自动做生序排序
新增功能: 新增了一些能够比较的相关功能
常用方法:
TreeSet<Integer> set = new TreeSet<>();
set.add(5);
set.add(2);
set.add(1);
set.add(3);
set.add(4);
System.out.println(set);
E ceiling(E e) 返回此set中大于或等于给定元素的 null元素,如果没有这样的元素,则 null 。
System.out.println(set.ceiling(6));
E first() 返回此集合中当前的第一个(最低)元素。
System.out.println(set.first());
E first() 返回此集合中当前的第一个(最低)元素。
System.out.println(set.first());
E higher(E e) 返回此集合中的最小元素严格大于给定元素,如果没有这样的元素,则 null 。
System.out.println(set.higher(1));
E pollFirst() 检索并删除第一个(最低)元素,如果此组为空,则返回 null 。
System.out.println(set.pollFirst());
E pollLast() 检索并删除最后一个(最高)元素,如果此集合为空,则返回 null 。
System.out.println(set.pollLast());
1.2 Comparable 比较器
TreeSet能自动排序是通过Comparable逐一比较
comparable分为内部比较器和外部比较器
内部比较器
内部比较器|自然排序 : 定义在一个类型的内部的比较方式
- java.lang.Comparable 接口
- 类型实现Comparable接口,重写compareTo(T o)方法,方法内部指定比较规则
- compareTo 返回值 int 类型 T1.compareTo(T2) -> 0: 相等 整数:T1>T2 负数:T1<T2
优点: 默认比较方式,定义在类的内部
缺点: 固定,硬编码,不够灵活
//实现Comparable接口,重写compareTo方法,自定义排序
public class Student implements Comparable<Student>{
private String name;
private int age;
private String ID;
public Student() {}
public Student(String name, int age, String ID) {
this.name = name;
this.age = age;
this.ID = ID;
}
//中间部分代码省略...
//重写compareTo排序方法
@Override
public int compareTo(Student o) {
return ID.compareTo(o.ID);//compareTo()比较两个字符串中间的大小
}
}
外部比较器
外部比较器|定制排序 : 定义在一个类型(要比较的对象数据的类型)的外部的比较方式
- 实现 java.util.Comparator接口,重写compare(T t1, T t2)定义比较规则
- 返回值: 0: 相等 正数:T1>T2 负数:T1<T2
注意: 如果使用的时候指定了定值排序使用定值排序,没有指定使用自然排序
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Integer> ts = new TreeSet<>();
//利用Lambda表达式简单的自定义排序规则
Comparator<Student> com = (o1,o2) -> o1.getID().compareTo(o2.getID());
TreeSet<Student> stu = new TreeSet<>(com);
stu.add(new Student("赵六",21,"1x004"));
stu.add(new Student("张三",20,"1x001"));
stu.add(new Student("钱七",20,"1x005"));
stu.add(new Student("李四",18,"1x002"));
stu.add(new Student("王五",24,"1x003"));
stu.add(new Student("777",20,"1x005"));
System.out.println(stu);
}
}
//继承Comparator接口,实现compare方法
class D implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge()- o2.getAge();
}
}
注意:在添加引用数据类型时,需继承Comparator接口,实现compare方法,不然会抛出ClassCastException异常
二,Map
2.1 Map接口
Map也是容器的一种,但是没有继承Collection接口,
以键值对的形式存放数据,一个key对应一 个value。key和value都是引用数据类型,
我们可以通过key找到对应的value
Map是无序的,不可重的
Map类中存储的键值对通过 键
来标识,所以 键值不能重复 。
注意:如果存入的键值对中key相同,那么后面的会覆盖掉前面的当数据存放到Map之后,我们是无法控制存放数据的顺序的
Map的简单应用
public static void main(String[] args) {
//创建Map集合
Map<Integer,String> map = new HashMap<>();
//V put(K key, V value) 将指定的值与此映射中的指定键相关联(可选操作)。
map.put(1001,"zhangsan");
map.put(1002,"lisi");
System.out.println(map.put(1003,"wangwu"));
System.out.println(map);
System.out.println(map.put(1002,"LISA"));
System.out.println(map);
//V get(Object key) 返回指定键映射到的值,如果此映射不包含键的映射,则返回 null 。
System.out.println(map.get(1001));
//boolean containsKey(Object key) 如果此映射包含指定键的映射,则返回 true 。
//boolean containsValue(Object value) 如果此映射将一个或多个键映射到指定值,则返回 true 。
System.out.println(map.containsKey(1003));
System.out.println(map.containsValue("zhangsan"));
//V remove(Object key) 如果存在,则从该映射中移除键的映射(可选操作)。
System.out.println(map.remove(1001));
System.out.println(map);
}
Map的遍历方式
Map集合遍历方式
- keySet 获取所有的key值,返回一个set集合
- values() 获取map集合中所有键值对的value,返回一个Collection集合
- ntrySet() 获取所有的键值对->Map.Entry 类型->表示一个键值对
public static void main(String[] args) {
//创建Map集合
Map<Integer,String> map = new HashMap<>();
map.put(1001,"zhangsan");
map.put(1002,"lisi");
map.put(1003,"wangwu");
//1.keySet
//将所有的 key 获取存入 Set 集合中,遍历存储 key 的 Set 集合,
//结合 get(key) 方法可以获取map 中每一个 key 以及对应的 value。
Set<Integer> keys= map.keySet();
for(Integer i:keys){
System.out.println(i+"-->"+map.get(i));
}
//2.values()
//将所有的 value 值获取后存入Collection集合中,遍历存储了所有 key 的集合,
//则可以获取到所有的value 值,但此种方式只能获取到每一个value,并不能获取到key。
Collection<String> col = map.values();
for(String s:col){
System.out.println(s);
}
//3)entrySet
//将Map集合中的每一个键值对作为一个 Entry 对象获取到一个Set集合中,
//通过对象的 getKey 和getValue 方法获取 key 和 value
Set<Map.Entry<Integer,String>> set = map.entrySet();
Iterator<Map.Entry<Integer,String>> it = set.iterator();
for(;it.hasNext();){
Map.Entry entry = it.next();
System.out.println(entry.getKey()+"-->"+entry.getValue());
}
}
2.2 HashMap
HashMap作为Map的实现类,其中的方法都进行了实现,并且定义了可以存储数据的空间,其中使用了 一个叫做 Entry 的内部类,作为数据的存储
底层结构: 哈希表(数组+链表+红黑树)
特点: 查询,增删效率较高
简单应用
Map<String, String> map = new HashMap<>();
map.put("1","一,壹,Ⅰ");
map.put("2","二,贰,Ⅱ");
map.put("3","三,叁,Ⅲ");
System.out.println(map.get("1"));
HashMap中存储数据的特点:
- 存储的元素是以K-V的形式存在的
- map集合中 key 必须要唯一,如果添加了相同的键值对(键相同)会发生覆盖
- map集合中元素(键值对)是无序的,和Set集合类似
三,各集合的特征
集合里面数据的特征:
- List(ArrayList,LinkedList):单个数据,数据是可以重复的,而且可以指定位置
- Set:单个数据,数据是不可以重复,而且是无序的(不由用户来指定位置|顺序)
- Map:成键值对的数据,数据是没有顺序的,键是不可以重复的
- hashCode在Set和Map集合中判断对象是否重复(相同)
- equals也是用来判断对象是否相同(重复)List,Set,Map
四,Properties
Properties为Hashtable的子类,要求键与值只能为字符串 ,不能为null,常与 配置文件(与外界交 互 的信息) 即内存与存储介质(文件、数据库、网络、服务器内存等)交互。
优点 : 可以通过Properties实现软编码,从满足Properties特点的配置文件中读取数据,便于后期维护
使用步骤:
- 定义一个配置文件 xx.properties (键值对都是字符串)
- 创建Properties类型的对象,调用load从流中加载(输入流的数据源就是配置文件)
- 从配置文件中读取数据,加载使用
Properties pro = new Properties();
// 通过当前线程获取ClassLoader
//void load(InputStream inStream) 从输入字节流中读取属性列表(键和元素对)。
pro.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties"));
System.out.println(pro.getProperty("userName"));
db.properties 配置文件
userName=zhangsan
userPwd=123