Properties
- map接口实现子类
- 1 properties类继承于 Hashtable 并且实现了map接口,也是一种使用kv对的形式来保存数据
2 使用特点于hashtable蕾丝
3 properties还可以用来从xxx.properties 文件中加载数据到properties类对象进行读取和修改
4 工作后 xxx.properties 文件通常作为配置文件,这个知识点将在io溜中学到
- 1 properties类继承于 Hashtable 并且实现了map接口,也是一种使用kv对的形式来保存数据
public static void main(String[] args) {
Properties properties = new Properties();
properties.put("1","addicated");
System.out.println(properties.get("1"));
// remove(key ) 进行删除
properties.remove("1");
properties.put("1","mengnan"); // 相同key 则修改value
/*
class Properties extends Hashtable<Object,Object> {
继承自hashtable
kv 不得为空
*/
// put 方法调用hashTable 的put方法。
}
TreeSet
- map接口的一个实现子类 区别于hashSet treeSet是有序的
- 底层实际上是 TreeMap
- 特点
// 1 当死使用午餐构造器的时候,treeSet 仍然是无序的
// 2 希望添加元素,按照字符串大小进行排序
// 3 使用treeSet 提供的一个构造器,可以传入一个比较器 使用匿名内部类的方式
// 并制定排序规则
// 4 简单分析源码
TreeSet treeSet = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
// 下面调用string的 compareTo方法进行字符串大小比较
return ((String) o1).compareTo((String) o2);
}
});
// 添加数据
treeSet.add("addicated");
treeSet.add("addicated1");
treeSet.add("addicated2");
treeSet.add("addicated3");
System.out.println(treeSet);
// 构造器
无参构造器去创建对象时, treeSet其实仍然是无序的。但是底层会调用String的compareTo方法作为比较规则来对插入进来的kv对进行排序。
public TreeSet() {
this(new TreeMap
public TreeMap(Comparator<? super K> comparator) { this.comparator = comparator; }
// add 方法底层
// 这个地方的 PRESENT 实际上与hashSet中的 处理一样,作为一个常量直接插入,以key来进行区分元素重复
public boolean add(E e) {
return m.put(e, PRESENT)==null;
}
public V put(K key, V value) {
Entry
root = new Entry<>(key, value, null);
size = 1;
modCount++;
return null;
}
int cmp;
Entry<K,V> parent;
// split comparator and comparable paths
Comparator<? super K> cpr = comparator; // cpr 实际上是构造器调用的时候传入的匿名内部类,即比较规则
if (cpr != null) {
do {
parent = t;
cmp = cpr.compare(key, t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else // 加入的值在 treeset中已经有的时候,comapre返回为0 走else 分支,
return t.setValue(value);
} while (t != null);
}
else {
if (key == null)
throw new NullPointerException();
@SuppressWarnings("unchecked")
Comparable<? super K> k = (Comparable<? super K>) key;
do {
parent = t;
cmp = k.compareTo(t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
Entry<K,V> e = new Entry<>(key, value, parent);
if (cmp < 0)
parent.left = e;
else
parent.right = e;
fixAfterInsertion(e);
size++;
modCount++;
return null;
}
*/
<a name="EDxz7"></a>
# TreeMap
- 与hashMap的区别就是有序,且可自定义排序规则
- 大部分特性与TreeSet相同,因为二者同根同源
```java
1 源码解读
public TreeMap(Comparator<? super K> comparator) {
this.comparator = comparator;
}
2 调用put 方法 ,
第一次添加直接吧 k-v 封装到 entry对象 放入 root
if (t == null) {
compare(key, key); // 传入参数为 key 其实两个参数相等,调用compare必等0 但是没有用变量去接收,也不影响下面代码的执行,只是在第一次添加元素的时候就调用一下compare检测是否为null,为null直接抛npe
root = new Entry<>(key, value, null);
size = 1;
modCount++;
return null;
}
第二次加入的时候启用比较器
Comparator<? super K> cpr = comparator;
if (cpr != null) {
do { // 遍历所有的key 给当前的key 找适当的位置,然后挂上去
parent = t;
cmp = cpr.compare(key, t.key); // 动态绑定到我们的匿名内部类的compare方法
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else // 如果遍历过程中,发现准备添加的key 和当前已经有的key 相等 疾苦直接返回,不进行添加
// hashMap 取决与equals方法,treeMap取决于传入的 匿名内部类中实现的compartor方法
// 按照 比较方法 得到 key相等的情况则直接不进行值插入
return t.setValue(value);
} while (t != null);
}
比较规则的传入
调用有参构造器 并且以匿名内部类的形式吧比较器传入即可
// 使用默认的构造器 创建treeMap 仍然是无需的 // 与treeSet一样,使用匿名内部类来定义比较规则 TreeSet treeSet = new TreeSet(new Comparator() { @Override public int compare(Object o1, Object o2) { return ((String) o1).compareTo((String) o2); } });
比较器注意点
treeMap treeSet的比较器,某种程度上接近 hashMap中先比较索引值之后调用equals 比较对象内容的功用。
- 但仍然有不同之处
if (cpr != null) { do { // 遍历所有的key 给当前的key 找适当的位置,然后挂上去 parent = t; cmp = cpr.compare(key, t.key); // 动态绑定到我们的匿名内部类的compare方法 if (cmp < 0) t = t.left; else if (cmp > 0) t = t.right; else // 如果遍历过程中,发现准备添加的key 和当前已经有的key 相等 疾苦直接返回,不进行添加 // hashMap 取决与equals方法,treeMap取决于传入的 匿名内部类中实现的compartor方法 // 按照 比较方法 得到 key相等的情况则直接不进行值插入 return t.setValue(value); } while (t != null); }