1、总结-开发中如何选择集合实现类
package set_;
import java.util.Comparator;
import java.util.TreeSet;
@SuppressWarnings({"all"})
public class TreeSet_ {
public static void main(String[] args) {
// 1. 当我们使用无参构造器, 创建 TreeSet 时, 仍然是无序的
// 2. 希望添加的元素, 按照字符串大小来排序
// 3. 使用 TreeSet 提供的一个构造器, 可以传入一个比较器(匿名内部类)
// 并指定排序规则
// TreeSet treeSet = new TreeSet();
TreeSet treeSet = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
// 下面 调用 String 的 compareTo 方法进行字符串大小比较
// return ((String) o2).compareTo((String) o1); // treeSet=[tom, li, john, jack, a]
// 要求加入的元素, 按照长度大小排序
return ((String) o1).length() - ((String) o2).length(); // treeSet=[a, li, tom, jack]
}
});
treeSet.add("jack");
treeSet.add("tom");
treeSet.add("john");
treeSet.add("li");
treeSet.add("a");
System.out.println("treeSet=" + treeSet);
}
}
/**
* 源码解读
* 1. 构造器把传入的比较器对象, 赋给了 TreeSet 的底层的 TreeMap 的属性 this.comparator
* public TreeSet(Comparator<? super E> comparator) {
* this(new TreeMap<>(comparator));
* }
*
* public TreeMap(Comparator<? super K> comparator) {
* this.comparator = comparator;
* }
* 2. 在 调用 treeSet.add("tom"), 在底层会执行到
* if (cpr != null) { // cpr 就是我们的匿名内部类(对象)
* do {
* parent = t;
* // 动态绑定到我们的匿名内部类(对象)compare
* cmp = cpr.compare(key, t.key);
* if (cmp < 0)
* t = t.left;
* else if (cmp > 0)
* t = t.right;
* else // 如果相等, 即返回 0, 这个 Key 就没有加入
* 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);
* }
*/
package set_;
import java.util.Comparator;
import java.util.TreeMap;
@SuppressWarnings({"all"})
public class TreeMap_ {
public static void main(String[] args) {
// 使用默认的构造器, 创建 TreeMap, 是无序的(也没有排序)
// 需求: 按照传入的 k(String) 的大小进行排序
// TreeMap treeMap = new TreeMap();
TreeMap treeMap = new TreeMap(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
// 按照传入的 k(String) 的大小进行排序
// 按照 K(String) 的长度大小排序
// return ((String) o2).compareTo((String) o1); // treemap={zwj=张无忌, tom=汤姆, smith=斯密斯, kristina=克瑞斯提诺, jack=杰克}
return ((String) o2).length() - ((String) o1).length();
}
});
treeMap.put("jack", "杰克");
treeMap.put("tom", "汤姆");
treeMap.put("kristina", "克瑞斯提诺");
treeMap.put("smith", "斯密斯");
treeMap.put("zwj", "张无忌"); // 加入不了
System.out.println("treemap=" + treeMap); // treemap={kristina=克瑞斯提诺, smith=斯密斯, jack=杰克, tom=张无忌}
}
}
/**
* 解读源码
* 1. 构造器 把传入的实现了 Comparator 接口的匿名内部类(对象), 传给给 TreeMap 的 comparator
* public TreeSet(Comparator<? super E> comparator) {
* this(new TreeMap<>(comparator));
* }
*
* public TreeMap(Comparator<? super K> comparator) {
* this.comparator = comparator;
* }
* 2. 调用 put 方法
* 2.1 第一次添加, 把 k-v 封装到 Entry 对象, 放入 root
* Entry<K,V> t = root;
* if (t == null) {
* compare(key, key); // type (and possibly null) check
*
* root = new Entry<>(key, value, null);
* size = 1;
* modCount++;
* return null;
* }
* 2.2 以后添加
* Comparator<? super K> cpr = comparator;
* if (cpr != null) { // 遍历所有的 key, 给当前 key 找到适当位置
* do {
* 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 相等, 就不添加
* 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);
* }
*/
2、Collections 工具类
2.1、Collections 工具类介绍
2.2、排序操作:(均为 static 方法)
查找、替换
代码实现
package collection_;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@SuppressWarnings({"all"})
public class Collections_ {
public static void main(String[] args) {
// 创建 ArrayList 集合, 用于测试
List list = new ArrayList();
list.add("tom");
list.add("smith");
list.add("king");
list.add("milan");
list.add("tom");
// reverse(List): 反转 List 中元素的顺序
Collections.reverse(list);
System.out.println("list=" + list); // list=[tom, milan, king, smith, tom]
// shuffle(List): 对 List 集合元素进行随机排序
for (int i = 0; i < 5; i++) {
Collections.shuffle(list);
System.out.println("list=" + list);
/**
* list=[tom, king, milan, smith, tom]
* list=[king, smith, milan, tom, tom]
* list=[king, milan, tom, tom, smith]
* list=[king, tom, tom, smith, milan]
* list=[tom, tom, milan, king, smith]
*/
}
// sort(List): 根据元素的自然顺序对指定 List 集合元素按升序排序
Collections.sort(list);
System.out.println("自然排序后");
System.out.println("list=" + list); // list=[king, milan, smith, tom, tom]
// sort(List,Comparator): 根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
// 希望按照 字符串的长度大小排序
Collections.sort(list, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
// 可以加入校验代码
return ((String) o2).length() - ((String) o1).length();
}
});
System.out.println("字符串长度大小排序=" + list); // 字符串长度大小排序=[milan, smith, king, tom, tom]
// swap(List, int, int): 将指定 list 集合中的 i 处元素和 j 处元素进行交换
Collections.swap(list, 0, 1);
System.out.println("交换后的情况");
System.out.println("list=" + list); // list=[smith, milan, king, tom, tom]
// Object max(Collection): 根据元素的自然顺序, 返回给定集合中的最大元素
// 比如, 我们要返回长度最大的元素
Object maxObject = Collections.max(list, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return ((String) o1).length() - ((String) o2).length();
}
});
System.out.println("长度最大的元素=" + maxObject); // 长度最大的元素=smith
// Object min(Collection)
// Object min(Collection,Comparator)
// 上面的两个方法, 参考 max 即可
// int frequency(Collection,Object): 返回指定集合中指定元素的出现次数
System.out.println("tom 出现的次数=" + Collections.frequency(list, "tom")); // tom 出现的次数=2
// void copy(List dest,List src): 将 src 中的内容复制到 dest 中
ArrayList dest = new ArrayList();
// 为了完成一个完整拷贝, 我们需要先给 dest 赋值, 大小和 list.size()一样
for (int i = 0; i < list.size(); i++) {
dest.add("");
}
// 拷贝
Collections.copy(dest, list);
System.out.println("dest=" + dest); // dest=[smith, milan, king, tom, tom]
// boolean replaceAll(List list, Object oldVal, Object newVal): 使用新值替换 List 对象的所有旧值
// 如果 list 中, 有 tom 就替换成 汤姆
Collections.replaceAll(list, "tom", "汤姆");
System.out.println("list=" + list); // list=[smith, milan, king, 汤姆, 汤姆]
}
}