Java 集合的知识点
集合的部分知识点:
package JavaCollection;
import org.junit.jupiter.api.Test;
import java.util.*;
/**
* 一、 集合的概述
* 1 集合、数组都是对多个数据进行存储操作的结构,简称Java 容齐
* 说明: 此时的存储,主要指的是内存层次的存储,不涉及到持久化的存储
*
* 2.1 数组在存储多个数据方面的特点:
* · 一旦初始化以后,其长度就确定了
* · 数组一旦定义好,其元素的类型就确定了。我们就只能操作其指定个类型的数据了
* 比如: String[ ] arr = new String[5];
*
* 2.2 数组在存储多个数据方面的缺点:
* · 一旦初始化以后,其长度不能修改了
* · 数组中提供的方法非常有限,对于添加、删除、插入数据等操作,非常不便,效率低
* · 获取数组中实际元素的个数的需求,数组没有现成的属性或方法
* · 数组存储的特点: 有序、可重复。对于无序、不可重复的需求,不能满足
*
*
*
* 二、集合框架
* |---- Collection 接口:单列集合,用于存储一个一个的对象
* | --- List 接口: 存储有序的、可重复的数据。 也叫做"动态 数组"
* | -- ArrayList LinkedList Vector
* | --- Set 接口: 存储无序的、不可重复的数据 --> 高中间的 " 集合 "
* | -- HashSet LinkedSet TreeSet
*
* | ---- Map 接口:双列集合, 用于存储一对(Key - value)一对数据
* | -- HashMap LinkedMap TreeMap HashTable Properties
*
* 三、 Collection 接口中的方法的使用
*/
public class CollectionTest{
@Test
public void test(){
Collection coll = new ArrayList();
// 1 add(Object e); 将元素e 添加到集合coll中
coll.add("AA");
coll.add("AA"); // 可重复
coll.add(123); // 自动装箱
coll.add(new Date());
// 2 size(); 获取添加的元素的规格书
System.out.println(coll.size());
// 3 addAll(); 将集合coll1 中的元素都装到coll中
Collection coll1 = new ArrayList();
coll1.add(456);
coll1.add("CC");
// coll.addAll(coll); 可以把自己重新装一此,相当于复制了
coll.addAll(coll1);
System.out.println(coll.size());
System.out.println(coll);
// 4 isEmpty(); 判断当前集合是否有元素
System.out.println(coll.isEmpty());
System.out.println("******************");
// 5 clear(); 清空集合元素
coll.clear();
//isEmpty(); 判断当前集合是否有元素
System.out.println(coll.isEmpty());
}
@Test
public void test1(){
Collection coll2 = new ArrayList();
coll2.add(123);
coll2.add(456);
coll2.add("Tom");
coll2.add(new String("Tom"));
coll2.add(new Person("Jerry",20));
coll2.add(false);
// 6 contains(Object obj); 判断当前集合中是否包含obj
boolean contains = coll2.contains(123);
System.out.println(contains);
//contains 其实是调用 比较对象的 类中的比较器也就是equals()的方法
// String 重写了equals 比的是内容
System.out.println(coll2.contains(new String("Tom"))); // true
// 用的是Object 类中的 比较 在Object 中没有重写equals 所以 是false
// 但是通过改写equals的方法 可以重新定义 让false-- true
System.out.println(coll2.contains(new Person("Jerry",20))); //false
// 7 containsAll(Collection coll3); 判断形参coll3中的所有元素是否都在当前集合中
Collection coll3 = Arrays.asList(123,456);
System.out.println(coll2.containsAll(coll3));
}
@Test
public void Test2(){
// 8 remove(Object obj);
Collection coll1 = new ArrayList();
coll1.add(123);
coll1.add(456);
coll1.add("Tom");
coll1.add(new String("Tom"));
coll1.add(new Person("Jerry",20));
coll1.add(false);
coll1.remove(123);
System.out.println(coll1);
// 9 removeAll(); 差集的操作:从当前集合中移除coll2中所有的元素
Collection coll2 = Arrays.asList(123,456);
coll1.removeAll(coll2);
System.out.println(coll1);
}
@Test
public void test3(){
Collection coll2 = new ArrayList();
coll2.add(123);
coll2.add(456);
coll2.add("Tom");
coll2.add(new String("Tom"));
coll2.add(new Person("Jerry",20));
coll2.add(false);
Collection coll3 = Arrays.asList(123,456);
// 10 retainAll(Collection coll3); 交集: 获取当前集合和coll3集合的交集
// 对于该集合的操作,并没有创建一个新的Collection 只是删除了 不一样的元素,保存了一样的元素
// coll2.retainAll(coll3);
// System.out.println(coll2);
// 11 equals(Object obj);
Collection coll4 = new ArrayList();
coll4.add(123);
coll4.add(456);
coll4.add("Tom");
coll4.add(new String("Tom"));
coll4.add(new Person("Jerry",20));
coll4.add(false);
System.out.println(coll2.equals(coll4));
}
@Test
public void test4(){
Collection coll2 = new ArrayList();
coll2.add(123);
coll2.add(456);
coll2.add("Tom");
coll2.add(new String("Tom"));
coll2.add(new Person("Jerry",20));
coll2.add(false);
// 12 hashCode(); 返回当前对象的hash值
System.out.println(coll2.hashCode());
// 13 集合 --> 数组: toArray();
Object[] arr = coll2.toArray();
for (int i = 0; i <arr.length ; i++) {
System.out.print(arr[i]+ " ");
}
//拓展: 数组 --> 集合: 调用Arrays类的静态方法
List<String> list = Arrays.asList(new String[]{"AA", "BB", "CC"});
}
// 14 集合元素的遍历,使用迭代器Iterator接口
// Iterator 是一个接口 所有要使用的话 需要实现接口的对象
// 1 内部方法: hasNext() 和 Next()
// 2 集合对象每次调用iterator()方法都得到一个全新的迭代器对象,
// 默认游标都在集合 的第一个元素之前。
// 3 迭代器内部定义了remove方法, 可以在遍历的时候删除 集合的元素
// 但是该方法不是collection的remove 而是迭代器的remove
@Test
public void test5(){
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add("Tom");
coll.add(new String("Tom"));
coll.add(new Person("Jerry",20));
coll.add(false);
// 方式一: 推荐
Iterator iterator = coll.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//方式二: 不推荐
for (int i = 0; i <coll.size() ; i++) {
System.out.println(iterator.next());
}
// 因为迭代器 每次调用iterate 方法 都会得到一个全新的迭代器对象,
// 所以不能用这种while的方式实现遍历
// 因为每次while condition里面的语句都会生成一个iterate 迭代器
// 每个迭代器都会产生一个指针并指向list 首行之上, 所以输出总是123 123 的死循环
// while(coll.iterator().hasNext()){
// System.out.println(coll.iterator().next());
// }
}
// 测试remove() 方法
@Test
public void test6(){
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add("Tom");
coll.add(new String("Tom"));
coll.add(new Person("Jerry",20));
coll.add(false);
// 删除集合中的"Tom"
// 如果还未调用next()或在上一次调用 next 方法之后已经调用了 remove 方法,
// 再调用remove都会报IllegalStateException。 ( 分析指针就能理解)
Iterator iterator = coll.iterator();
System.out.println(iterator);
while(iterator.hasNext()){
if (iterator.next().equals("Tom")) {
iterator.remove();
}
}
iterator = coll.iterator();
System.out.println(iterator);
// 这两个iterate 的地址值是不一样的
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
// JDK 5.0 新增foreach循环,用于遍历集合和数组
@Test
public void test7(){
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add("Tom");
coll.add(new String("Tom"));
coll.add(new Person("Jerry",20));
coll.add(false);
Iterator iterator = coll.iterator();
//for(集合元素类型 局部变量/形参 : 集合对象)
// 内部仍然调用的是迭代器
for (Object obj: coll){
System.out.println(coll);
}
}
@Test
public void testForEach(){
String[] str = new String[]{"Jerry","Tom","Janna","Jakob"};
for (String strForEach:str){
System.out.println(strForEach);
}
}
}
Collection 的子接口: List 接口
package JavaCollection;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* |---- Collection 接口:单列集合,用于存储一个一个的对象
* | --- List 接口: 存储有序的、可重复的数据。 也叫做"动态 数组",替代原有的数组
* | -- ArrayList: 作为List的主要实现类 JDK 1.2
* | -- LinkedList: JDK 1.2
* | -- Vector: 作为List 的古老实现类 JDK 1.0
*
* 三者的异同?
* 同: 三个类都实现了List接口,特点:存储有序的、可重复的数据。
* 不同;
* ArrayList: 线程不安全,效率高;底层与Vector相似,都是用Object[] 的数组存储
* LinkedList: 对于频繁的插入、删除等操作,使用该类效率高,底层使用的是双向链表存储
* Vector:线程安全,效率低;底层与ArrayList相似,都是用Object[] 的数组存储
*
*
* ArrayList 源码框架
* ArrayList 源码分析: JDK 7
* ArrayList list = new ArrayList(); 底层创建了长度为10 的Object[] 数组
*
* 关于扩容: 默认情况下,扩容为原来的1。5倍,同时需要将原来的数组中的数据复制到新的数组中
*
* 开发中,建议使用带参的构造器: 避免扩容
*
* ArrayList 源码分析: JDK 8
* 变化: ArrayList list = new ArrayList(); 底层创建的是{}, 并没有一开始就定义数组的默认长度
* 好处是,延迟了数组的创建时间,减少了存储负担,要等到调用第一个add的时候才定义默认长度,其它操作都与7 一样
* JDK 7 有点想单例的饿汉式,JDK 8 有点想懒汉式
*
* ***********************************************************************************
* LinkedList 源码分析
* LinkedList list = new LinkedList(); 内部声明了Node类型的first 和 last。 默认值为null
* add 其实是先调用last Node 的方法 创建一个新的Node prev 是之前的last item 是本次添加的数据
* last 定义为null。 然后 判断prev 是否是null。如果是则Node prev 是null
*
* 说明: 链表不需要考虑扩容
*
*/
public class ListTest {
/**
* void add(int index, Object ele):在index位置插入ele元素
* boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来
* Object get(int index):获取指定index位置的元素
* int indexOf(Object obj):返回obj在集合中首次出现的位置
* int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置
* Object remove(int index):移除指定index位置的元素,并返回此元素
* Object set(int index, Object ele):设置指定index位置的元素为ele
* List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex位置的子集合
*
*
* 常用方法:
* 增:add
* 插:add(int index, Object obj)
* 删:remove
* 改:set
* 查:get
* 长度:size
* 遍历:1. Iterate迭代器 2.forEach 3.for普通循环
*/
@Test
public void Test1(){
ArrayList list = new ArrayList();
list.add(123);
list.add(456);
list.add(456);
list.add("Jerry");
list.add(new Person("Tom",12));
System.out.println(list);
// 1 void add(int index, Object ele):在index位置插入ele元素
list.add(1,"AA");
// 2 boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来
List list1 = Arrays.asList(567,678,"Janna");
list.addAll(list1);
System.out.println(list.size());
// 3 Object get(int index):获取指定index位置的元素
System.out.println(list.get(1));
}
@Test
public void test2() {
ArrayList list = new ArrayList();
list.add(123);
list.add(456);
list.add(456);
list.add("Jerry");
list.add(123);
list.add(new Person("Tom", 12));
// 4 int indexOf(Object obj):返回obj在集合中首次出现的位置
System.out.println(list.indexOf(123));
// 5 int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置
System.out.println(list.lastIndexOf(123));
// 6 Object remove(int index):移除指定index位置的元素,并返回此元素
System.out.println(list.remove(1));
// 7 Object set(int index, Object ele):设置指定index位置的元素为ele
list.set(1, "CC");
System.out.println(list);
// 8 List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex位置的子集合
List subList = list.subList(2, 4);
System.out.println(list);
System.out.println(subList);
}
}
Collection 的子接口: Set 接口
HashSet 的存储过程:
注: HashSet的存储即使用了数组,也涉及链表
当我们想想HashSet添加元素的时候,首先会HashSet会调用hashCode 的方法,去给该元素生成一个hashCode值,然后通过底层的散列函数的计算 去响应该元素在HashCode里面的存储位置,(一开始 HashSet生成的初始化数组的默认长素是16。
因为长度有限,这时候就可能会有两个不同的hash值通过散列函数计算的结果是一样的,也就是说可能会对应同一个位置(也就是数组中的下标)这时候就会使用链表去存储。JKD 8 之后是本来的元素指向 新增的元素( 7 上 8 下)。
由于Set 是无序的,不可重复的
当我们的hashSet有添加数据的时候,要判断两个点,一个是hashCode()一个是 equlas() 两个方法。使用使用Set类时(比如 : Set Person Class) 一定要重写这两个方法。
比较新增的数据: 首先要对hashCode进行比较,如果两个两个hashCode不同,但是指向的位置相同,则链表的方式存。 如果hashCode相同那么就要调用equals的方法了,判断内容是否也相同。true 添加失败,false 链表的方式存储。
对于HashSet 的扩容:
底层也是数组,初始容量为16,当如果使用率超过0.75,(16*0.75=12) 就会扩大容量为原来的2倍。(16扩容为32,依次为64,128…等)
package JavaCollection;
import org.junit.jupiter.api.Test;
import java.util.*;
/**
* | --- Set 接口: 存储无序的、不可重复的数据 --> 高中间的 " 集合 "
* | -- HashSet: 作为Set接口的主要实现类;线程不安全的; 可以存储Null
* | -- LinkedSet:是HashSet 的子类,遍历其内部数据时,可以按照添加的顺序遍历
* | -- TreeSet: 使用二叉树存储的,添加的元素必须是同一个类new 的对象
* 可以按照添加的元素的指定属性进行排序。
*
* 说明: Set接口没有额外的定义方法,都是父类Collection的方法
*/
public class SetTest {
/**
* Set 接口: 存储无序的、不可重复的数据
* 1 无序性: 不等于随机性,存储的数据在底层数组中并非按照数组索引的顺序添加,
* 而是按照数组中的hash值决定。
*
* 2 不可重复性
*
* HashSet的存储方式: 见上解析
*
*
*/
//LinkedHashSet 的使用
@Test
public void Test1(){
Set set = new HashSet();
set.add(456);
set.add(123);
set.add("Jerry");
set.add("AA");
set.add(123);
set.add(new Person("Tom",12));
// 输出的方式 是按照Hash对于的位置 打印的,不是按照添加的顺序
System.out.println(set);
System.out.println(set);
}
@Test
public void Test2(){
// LinkedHashSet 作为HashSet的子类 进行了改进
// 在添加数据的同时,同时也维护了两个引用,一个是该数据前面的数据是谁,另一个是该数据后面的数据是谁
// 优点: 对于频繁的遍历操作,LinkedHashSet 效率高
Set set = new LinkedHashSet();
set.add(456);
set.add(123);
set.add("Jerry");
set.add("AA");
set.add(123);
set.add(new Person("Tom",12));
// 按照输入的 顺序输出
System.out.println(set);
}
//treeSet 的使用: 可以按照添加的元素的指定属性进行排序。
// 1 treeSet 中的数据 必须是同一个类的 对象
// 2 两种排序方式: 自然排序 和 定制排序
// 3 既然有了排序 如果 添加的值 有多个属性的话,那我们就要在添加元素所在的类中重写 compareTo的方法
@Test
public void Test3(){
TreeSet set = new TreeSet();
// set.add(456);
// set.add(123);
// set.add(243);
// set.add(-222);
// set.add(123);
// System.out.println(set);
// 类中重写了 compare 的方法
set.add(new Person("Jerry",20));
set.add(new Person("Tom",30));
set.add(new Person("Jerry",22));
set.add(new Person("Tom",20));
set.add(new Person("Joker",40));
System.out.println(set);
}
@Test
public void test4(){
Comparator com = new Comparator() {
// 按照年龄从小到大排序
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Person && o1 instanceof Person) {
Person p1 = (Person)o1;
Person p2 = (Person)o2;
return Integer.compare(p1.getAge(),p2.getAge());
}
throw new RuntimeException();
}
};
TreeSet set = new TreeSet(com);
set.add(new Person("Jerry",20));
set.add(new Person("Tom",30));
set.add(new Person("Jerry",22));
set.add(new Person("Tom",20));
set.add(new Person("Joker",40));
System.out.println(set);
}
}
Map 的知识点
首先Map与Collection 是并存的关系
主要需要了解Map的存储方式 和 对结构的理解 见代码注释!
JDK 7 源码分析:
package JavaMap;
/**
* 一、 Map 的 结构框架
* | --- Map: 双列数据,用于存储 key - value 对的数据
* | --- hashMap: 作为Map的主要实现类; 线程不安全,效率高; 可以存储null的key 和 value
* | --- LinkedHashMap:保证在遍历map元素时,可以按照添加的顺序实现遍历。
* 原因: 在原有的HashMap底层结构的基础上,添加了一对指针
* 对于频繁的遍历操作,此类的执行效率高于HashMap
* | --- TreeMap:保证按照添加的key - value 的元素 按照key值进行排序操作。所以这里定义自然排序或者定制排序
* | --- Hashtable:作为古老的实现类;线程安全,效率低; 不可以存储null的key 和 value
* 底层使用红黑树
* | --- Properties:常用来处理配置文件。key 和 value 都是 String 类型
*
* HashMap 的底层: 数组+链表 (JDK 7之前)
* 数组+链表+红黑树(JDK 8)
*
* 二、Map的结构理解:
* Map中的key: 无序的、不可重复的,相当于是使用Set存储所有的key
* 所以说,key所在的类肯定要重写equals 和 hashCode 的方法 (以HashMap 为例)用于存储和查找
* TreeMap 是要重写CompareTo 或者 Comparator (链表的 是以自然排序和定制排序 去对比的)
* Map中的Value: 无序的、可重复的,相当于使用Collection存储所以的Value
* 所以说,因为是课重复的,是需要重写equals的方法即可,用于存储和查找
* 一个键值对: key-value 其实在存储的时候形成键值对,构成了一个Entry对象
* Map中的Entry; 无序的、不可重复的,使用Set存储所以的Entry
*
***********************************************************************************************
*
* 三、HashMap的底层实现原理:
* JDK 7:
* HashMap map = new HashMap();
* 在实例化以后,底层创建了一饿长度是16的一维数组Entry[].
* ...可能执行过多次put...
* map.put(key1,value1);
* --在对map进行添加数据时,首先,要点用key1所在类的hashCode() 方法,计算key1的hash值,还是跟set一样,
* 通过算法的计算之后,会得到一个该Entry元素在数组中的位置。
* 如果此位置上的数据为空,此时key1-value1元素添加成功;
* 如果此位置上的数据不为空,(意味着此位置上存在一个或多个数据(以链表的形式存放)),则需要比较key1和
* 已经存放的一个或者多个数据的hash值。
* 如果key1的hash值和已经存在的数据的hash值都不一样,则元素添加成功;
* 如果key1的hash值和已经存在的某一个数据的hash值都一样:则需要继续比较,调用key1所在类的equals方法
* 如果比较最后equals返回false: key1-value1 添加成功
* 注意: 如果比较最后equals返回true: 这里并不是说不添加该元素,而是把新添加的key1 对应的 value值 去替换掉原先存进去的值!
*
* 关于扩容:扩容为原来的2倍,复制之前的内容
* 当size>= 临界值是(临界值是0.75 Size) 并且要存放的位置非空时,扩容
*
* JDK 8 : 相较于 7 的不同:
* 与7 存储的数组类型不同,JDK 8 底层数组是Node[],而非Entry[]
* 和List 相似,一开始 New HashMap()时,底层并没有创建一个长度为16的数组,
* 而是在首次调用put() 方法时生成一个长度为16 的数组
* JDK8 底层结构: 数组+链表+红黑树
*
* 什么时候会设计到红黑树: 当数组的某一个索引位置上以链表形式存在的数据个数>8
* 并且当前数组的长度>64时。此时此索引位置上的所有数据改用红黑树存储。
*
*
*
* HashMap 和 Hashtable的异同
*
*
*/
public class MapTest {
}
Map当中定义的方法:
HashMap 常用的方法
package JavaMap;
import org.junit.jupiter.api.Test;
import java.util.*;
/**
* Map定义的方法:
* 添加、删除、修改操作:
* Object put(Object key,Object value):将指定key-value添加到(或修改)当前map对象中 void putAll(Map m):将m中的所有key-value对存放到当前map中
* Object remove(Object key):移除指定key的key-value对,并返回value
* void clear():清空当前map中的所有数据
*
* 元素查询的操作:
* Object get(Object key):获取指定key对应的value
* boolean containsKey(Object key):是否包含指定的key
* boolean containsValue(Object value):是否包含指定的value
* int size():返回map中key-value对的个数
* boolean isEmpty():判断当前map是否为空
* boolean equals(Object obj):判断当前map和参数对象obj是否相等
*
* 元视图操作的方法:
* Set keySet():返回所有key构成的Set集合
* Collection values():返回所有value构成的Collection集合
* Set entrySet():返回所有key-value对构成的Set集合
*
*
*/
public class MapMethods {
/**
* Object put(Object key,Object value):将指定key-value添加到(或修改)当前map对象中 void putAll(Map m):将m中的所有key-value对存放到当前map中
* Object remove(Object key):移除指定key的key-value对,并返回value
* void clear():清空当前map中的所有数据
*/
@Test
public void test1(){
Map map = new HashMap();
//添加
map.put("AA",123);
map.put(45,123);
map.put("BB",567);
// 修改
map.put("AA",789);
System.out.println(map);
Map map1 = new HashMap();
map1.put("CC",123);
map1.put("DD",123);
map.putAll(map1);
System.out.println(map);
//remove(Object key):
map.remove("CC");
//void clear():清空当前map中的所有数据
map.clear();
System.out.println(map);
System.out.println(map.size());//0
}
/**
* * 元素查询的操作:
* * Object get(Object key):获取指定key对应的value
* * boolean containsKey(Object key):是否包含指定的key
* * boolean containsValue(Object value):是否包含指定的value
* * int size():返回map中key-value对的个数
* * boolean isEmpty():判断当前map是否为空
* * boolean equals(Object obj):判断当前map和参数对象obj是否相等
*/
@Test
public void test2() {
Map map = new HashMap();
map.put("AA", 123);
map.put(45, 123);
map.put("BB", 567);
// Object get(Object key):获取指定key对应的value
System.out.println(map.get(45));
// boolean containsKey(Object key):是否包含指定的key
boolean isExit = map.containsKey("BB");
System.out.println(isExit);
// boolean containsValue(Object value):是否包含指定的value
isExit = map.containsValue(123);
System.out.println(isExit);
// boolean isEmpty():判断当前map是否为空
map.clear();
System.out.println(map.isEmpty());
}
/**
* * 元视图操作的方法:
* * Set keySet():返回所有key构成的Set集合
* * Collection values():返回所有value构成的Collection集合
* * Set entrySet():返回所有key-value对构成的Set集合
*/
@Test
public void test3(){
Map map = new HashMap();
map.put("AA", 123);
map.put(45, 123);
map.put("BB", 567);
// Set keySet():返回所有key构成的Set集合
Set set = map.keySet();
Iterator iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("**********************");
// 遍历所以的Value: Collection values():返回所有value构成的Collection集合
Collection values = map.values();
for (Object obj: values){
System.out.println(obj);
}
System.out.println("**********************");
// Set entrySet():返回所有key-value对构成的Set集合
// 方式一:
Set entrySet = map.entrySet();
for (Object obj: entrySet){
System.out.println(obj);
}
//方式二:
Set keySet = map.keySet();
iterator = keySet.iterator();
while (iterator.hasNext()){
Object key = iterator.next();
Object value = map.get(key);
System.out.println(key + " -- " + value);
}
}
}
TheeMap 的知识点
package JavaMap;
import org.junit.jupiter.api.Test;
import java.util.*;
/**
* TreeMap 中方法的使用:
* 向TreeMap中添加key-value,要求key必须是由同一个类创建的对象
* 因为要按照key进行排序,自然排序 定制排序。
* 所以说当使用TreeMap创建对象时,对象需要重写CompareTo的方法
*
*
*/
public class TreeMapTest {
@Test
public void test1(){
TreeMap treeMap = new TreeMap();
User user1 = new User("Tom", 23);
User user2 = new User("Jerry", 45);
User user3 = new User("Jack", 22);
User user4 = new User("Jason", 23);
treeMap.put(user1,98);
treeMap.put(user2,100);
treeMap.put(user3,198);
treeMap.put(user4,298);
Set keySet = treeMap.entrySet();
Iterator iterator = keySet.iterator();
while (iterator.hasNext()){
Object key = iterator.next();
Map.Entry entry = (Map.Entry)key;
System.out.println(entry.getKey() + " -- " + entry.getValue());
}
}
// 定制排序
@Test
public void test2(){
TreeMap treeMap = new TreeMap(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof User && o2 instanceof User) {
User u1 = (User)o1;
User u2 = (User)o2;
return Integer.compare(u1.getAge(),u2.getAge());
}
throw new RuntimeException();
}
});
User user1 = new User("Tom", 23);
User user2 = new User("Jerry", 45);
User user3 = new User("Jack", 22);
User user4 = new User("Jason", 23);
treeMap.put(user1,98);
treeMap.put(user2,100);
treeMap.put(user3,198);
treeMap.put(user4,298);
Set keySet = treeMap.entrySet();
Iterator iterator = keySet.iterator();
while (iterator.hasNext()){
Object key = iterator.next();
Map.Entry entry = (Map.Entry)key;
System.out.println(entry.getKey() + " -- " + entry.getValue());
}
}
}
class User implements Comparable{
private String name;
private int age;
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
if (age != user.age) return false;
return name != null ? name.equals(user.name) : user.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
@Override
public int compareTo(Object o) {
if (o instanceof User) {
User user = (User) o;
if (this.name.equals(user.name)) {
return Integer.compare(this.age,user.age);
}
return this.name.compareTo(user.name);
}else {
throw new RuntimeException();
}
}
}
Map 实现类 Properties
package JavaMap;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
/**
* Map 实现类 Properties
* Properties 类是 Hashtable 的子类,该对象用于处理属性文件
* Properties 里的 key 和 value 都是字符串类型
*
* 一般用于读取配置文件
*/
public class PropertiesTest {
public static void main(String[] args) throws IOException {
Properties properties = new Properties();
FileInputStream inputStream = new FileInputStream("jdbc.properties");
properties.load(inputStream);
String name = properties.getProperty("name");
String password = properties.getProperty("password");
System.out.println(name + " " + password);
}
}
Coleections工具类常用方法
Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素
Object min(Collection)
Object min(Collection,Comparator)
int frequency(Collection,Object):返回指定集合中指定元素的出现次数 void copy(List dest,List src):将src中的内容复制到dest中
boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值
void copy(List dest,List src):将src中的内容复制到dest中:
// 不能用 List dest = new ArrayList(src.size());
// sout(dest.size); 此时为0
去定义dest的长度,因为size指的是数组的长度,而不是说造几个对象
正确的写法:
List dest = new ArrayList(new Object[list.size()]);
copy(List dest,List src);