文章目录
一、Set集合
Set 接口 集 : 数据是唯一存储,无序的。
HashSet实现类:
底层 数据结构 哈希表。
1.HashSet
数组 + 链表 + 二叉树。
原理:
原码:
/*
* new HashSet:
* 加载因子:
* static final float DEFAULT_LOAD_FACTOR = 0.75f;
*
* 数组的初始容量: 16
* static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
* 二叉树节点临界值:
* static final int TREEIFY_THRESHOLD = 8;
*
*/
HashSet<String> set = new HashSet<>();
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node<K,V>[] tab; Node<K,V> p; int n, i;
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else {
Node<K,V> e; K k;
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
else if (p instanceof TreeNode)
e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
else {
for (int binCount = 0; ; ++binCount) {
if ((e = p.next) == null) {
p.next = newNode(hash, key, value, null);
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;
}
}
}
}
Set<String> set = new HashSet<>();
set.add("ab");
set.add("ac");
set.add("ba");
System.out.println(set);// [ab, ac, ba]
set.add("ab");
System.out.println(set);// [ab, ac, ba]
重写:hashCode和equals()方法:
class Student{
private int no;
private String name;
public Student(int no, String name) {
this.no = no;
this.name = name;
}
public int getNo() {
return no;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Student [no=" + no + ", name=" + name + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + no;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)// guojing.equals(guojing)
return true;
if (obj == null)// guojing.equals(null)
return false;
if (this.getClass() != obj.getClass())// guojing.equals("hello")
return false;
Student other = (Student) obj;//
if (no != other.no)
return false;
return true;
}
/* @Override
public int hashCode() {
return no;
}
@Override
public boolean equals(Object obj) {
// 只要学号相同 那么 就返回 true
// this.no (Student)obj .no
Student stu = (Student)obj;//
return this.no == stu.no;
}*/
}
public class TestHashSet1 {
public static void main(String[] args) {
Set<Student> set = new HashSet<>();
Student guojing = new Student(11, "郭靖");
Student yangkang = new Student(11, "郭靖");
Student huangrong = new Student(22, "黄蓉");
set.add(guojing);
set.add(yangkang);
set.add(huangrong);
//信息
set.forEach(System.out::println);
}
}
2、TreeSet
基本应用:
public static void main(String[] args) {
// 默认: 自然升序排序 Comparable
// Set<String> set = new TreeSet<>();
// Comparator
Set<String> set = new TreeSet<>((s1,s2)->s2.compareTo(s1));
set.add("aa");
set.add("cc");
set.add("bb");
// System.out.println(set);// [aa, bb, cc]
System.out.println(set);// [cc, bb, aa]
}
底层:二叉树
树:由分支关系组成的层次结构。
去重:
class Employee implements Comparable<Employee>{
private int no;
private String name;
private int age;
public Employee(int no, String name, int age) {
super();
this.no = no;
this.name = name;
this.age = age;
}
public int getNo() {
return no;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return "Employee [no=" + no + ", name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(Employee o) {
// 按照年龄 升序
int n = this.age - o.age;
if( n == 0)
return this.no - o.no;
return n;
}
}
public class TestTreeSet1 {
public static void main(String[] args) {
Set<Employee> set = new TreeSet<>();
Employee guojing = new Employee(11, "郭靖", 20);
Employee yangkang = new Employee(33, "杨康", 20);
Employee huangrong = new Employee(22, "黄蓉", 20);
set.add(guojing);
set.add(yangkang);
set.add(huangrong);
// -----------------------------
set.forEach(System.out::println);
}
}
3.区别
HashSet :底层 哈希表。
hashCode() ,equals() 重写自己去重。
唯一,无序。
LinkedHashSet: 底层 链表。
唯一,有序,添加的顺序维护。
TreeSet: 底层 二叉树。
唯一,有序,默认 Comparable自然排序,自己定制顺序Comparator .
HashSet > LinkedHashSet>TreeSet
// 无序
// Set<String> set = new HashSet<>();
// Set<String> set = new LinkedHashSet<>();
Set<String> set = new TreeSet<>((s1,s2)->s2.compareTo(s1));
set.add("aa");
set.add("bb");
set.add("ab");
set.add("cc");
// System.out.println(set);// [aa, bb, cc, ab] HashSEt
//-------------顺序--------------------------------
// 元素添加的顺序
// System.out.println(set); // [aa, bb, ab, cc] LinkedHashSet
// 自己定制顺序
// System.out.println(set);// [aa, ab, bb, cc] 默认 Comparable顺序
System.out.println(set);// [cc, bb, ab, aa] Comparator降序
二、队列
public static void main(String[] args) {
// 创建了一个队列
// Queue<String> q = new ArrayDeque<>();
Queue<String> q = new LinkedList<>();
// 入队
q.add("aa");// 添加成功true ,失败 异常
q.add("bb");
q.offer("cc");// 添加成功true,失败 false;
// 要求:队列 不允许 添加null值。但是有个特殊的可以添加null值得LinkedList
q.add(null);// java.lang.NullPointerException
System.out.println(q);// [aa, bb, cc]
// 出队
// System.out.println(q.remove());// aa 删除成功返回元素,失败异常
// System.out.println(q.remove());// bb
// System.out.println(q.poll());// cc 删除成功返回元素,失败 null
// 循环出队
while(q.size() > 0) {
System.out.println(q.poll());
}
// 获得队头元素(获取并不删除)
// System.out.println(q.element());// aa 获得成功 返回元素,失败异常
// System.out.println(q.peek());// aa 获得成功返回元素,失败 null
// System.out.println(q.size());// 0
}
三、Collections
public static void main(String[] args) {
// LinkedList
List<String> list = new ArrayList<>();
// 添加
list.add("aa");
list.add("cc");
// 向集合中添加多个元素
Collections.addAll(list, "bb","dd","ee");
System.out.println(list);// [aa, cc, bb, dd, ee]
// 1. 排序:自然升序 Comparable List
Collections.sort(list);
System.out.println(list);// [aa, bb, cc, dd, ee]
// 2. List
// Collections.sort(list, (s1,s2)->s2.compareTo(s1));
// System.out.println(list);// [ee, dd, cc, bb, aa]
// 3. 二分查找:前提升序排序 存在 返回正数 (索引),不存在返回 -插入点-1
System.out.println(Collections.binarySearch(list, "cc"));// 2
// 4. 集合中最大的元素
System.out.println(Collections.max(list));// ee
// 5。 集合中最小的元素
System.out.println(Collections.min(list));// aa
// 6. List 反转集合元素
Collections.reverse(list);// [ee, dd, cc, bb, aa]
// 7. 获得 第二个参数元素 在集合中出现的次数
System.out.println(Collections.frequency(list, "aa"));// 1
Collections.addAll(list, "aa","aa");// [ee, dd, cc, bb, aa, aa, aa]
System.out.println(Collections.frequency(list, "aa"));// 3
// 8. 用第二个元素 替换掉集合中的 所有元素
Collections.fill(list, "hello");// [hello, hello, hello, hello, hello, hello, hello]
System.out.println(list);
}
四、Map
Map接口: 映射。 双列存储。
key/value
键/值 对
键是唯一的,值是可以重复的。
public static void main(String[] args) {
// 编号/数据
Map<Integer,String> map = new HashMap<>();
// 添加元素
map.put(11, "aa");
map.put(22, "bb");
map.put(33, "cc");
System.out.println(map);// {33=cc, 22=bb, 11=aa}
// 1. 键值对 的个数
System.out.println(map.size());// 3
// 2.
System.out.println(map.isEmpty());// false
// 3. 是否存在指定的键
System.out.println(map.containsKey(11));// true
// 4。 是否存在指定的值
System.out.println(map.containsValue("cc"));// true
// 5. 删除指定的键对应的键值对信息
map.remove(33);
System.out.println(map);// {22=bb, 11=aa}
// 6. 获取键的集合,Set 唯一
System.out.println(map.keySet());// [22, 11]
// 7. 获得值得集合,Collection
System.out.println(map.values());// [bb, aa]
// 8. 清空集合
map.clear();
System.out.println(map.isEmpty());// true
System.out.println(map.size());// 0
}
注意:
public static void main(String[] args) {
// TODO Auto-generated method stub
// 编号/数据
Map<Integer,String> map = new HashMap<>();
// Map<Integer,String> map = new LinkedHashMap<>();
// Map<Integer,String> map = new TreeMap<>();
// 添加元素
map.put(11, "aa");
map.put(22, "bb");
map.put(33, "cc");
System.out.println(map);//{33=cc, 22=bb, 11=aa}
map.put(null, null);// HashMap,LinkedHashMap支持
// map.put(11, "aa");// {null=null, 33=cc, 22=bb, 11=aa} 键是唯一得
map.put(11, "hello");// {null=null, 33=cc, 22=bb, 11=hello} 键冲突,会用新得值替换旧的值
System.out.println(map);
}
Map得遍历:
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<>();
// 添加元素
map.put(11, "aa");
map.put(22, "bb");
map.put(33, "cc");
System.out.println(map);// {33=cc, 22=bb, 11=aa}
// 遍历集合元素
// 1. 集合得forEach
map.forEach(new BiConsumer<Integer, String>() {
@Override
public void accept(Integer t, String u) {
System.out.println(t + "," + u);
}
});
// Lambda
map.forEach((k,v)->System.out.println(k + ":" + v));
// 2. Iterator
// 1) 分别遍历
map.keySet().iterator().forEachRemaining(System.out::println);
map.values().iterator().forEachRemaining(System.out::println);
// 2) map.entrySet() 获得得是键值对Entry得集合 ,类型Set
map.entrySet().iterator().forEachRemaining(e->{System.out.println(e.getKey()+","+e.getValue());});
}
Map区别:
HashMap: 键唯一,速度快。
无序的。
支持 null键 和null值。
LinkedHashMap: 键唯一,有序,按照元素添加的顺序维护的。
支持 null键 和null值。
TreeMap: 键唯一,有序,自己定制顺序,Comparator定制顺序(键)
不支持null键 和null值。
HashMap > LinkeHashMap > TreeMap