数组
- 数组是一个存放多个数据的容器
- 数据是同一个类型的
- 所有的数据是线性规则排列
- 可通过位置索引来快速定位访问数据
- 需明确容器长度
// 数组初始化
int[] a; // 没有new即没有申请内存空间
int[] a = new int[2]; // 数组长度为2,且元素都为0
int[] a = new int[]{ 1, 2, 3 }; // 逐个初始化
int[] a = { 1, 2, 3 };
JCF
- JCF是一个容器框架,容器框架是为了表示和操作容器而规定的一种标准体系结构
- 容器是能够存储数据的空间结构:如数组、列表、散列集等
- 容器框架主要有以下三个部分
- 对外的接口:容器中所能存储的抽象数据类型
- 接口的实现:可复用的数据结构
- 算法:对数据的查找和排序
在Java1.2以后Java推出了JCF
JCF主要是实现类:
- 列表(List、ArrayList、LinkedList)
- 集合(Set、HashSet、TreeSet、LinkedHashSet)
- 映射(Map、HashMap、TreeMap、LinkedHashMap)
JCF主要的算法类
- Arrays:对数组进行查找和排序等操作
- Collections:对Collection及其子类进行排序和查找操作
列表List
List主要实现:
- ArrayList(非同步的)
- LinkedList(非同步的)
- Vector(同步)
ArrayList
- 以数组实现的列表,不支持同步
- 利用索引位置可以快速定位访问
- 不适合指定位置的插入、删除的操作
- 适合变动不大,主要用于查询的数据
- 和Java数组相比,其容量可动态调整的
- ArrayList在元素填满容器时会自动扩充容器大小的50%
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(3);
list.add(2);
list.add(1);
list.add(4);
list.add(5);
list.add(new Integer(6));
System.out.println(list.get(3));
// 删除第4个元素,后面的元素会往前挪动
list.remove(3);
// 将9插入到第3个元素,后面元素会往后挪动
list.add(3, 9);
}
遍历性能测试:
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>(1000000);
for (int i = 0; i < 1000000; i++) {
list.add(i);
}
// 使用迭代器遍历
traverseByIterator(list);
// 按位置索引遍历
traverseByIndex(list);
// for-earch遍历
traverseByFor(list);
}
private static void traverseByFor(ArrayList<Integer> list) {
long startTime = System.nanoTime();
for (Integer item : list) {
;
}
long endTime = System.nanoTime();
System.out.println("for-earch遍历用时: " );
System.out.println( (endTime - startTime) + "纳秒");
}
private static void traverseByIndex(ArrayList<Integer> list) {
long startTime = System.nanoTime();
for (int i = 0; i < list.size(); i++) {
list.get(i);
}
long endTime = System.nanoTime();
System.out.println("索引遍历用时: ");
System.out.println( (endTime - startTime) + "纳秒");
}
private static void traverseByIterator(ArrayList<Integer> list) {
long startTime = System.nanoTime();
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
iterator.next();
}
long endTime = System.nanoTime();
System.out.println("迭代器遍历用时: ");
System.out.println( (endTime - startTime) + "纳秒");
}
运行结果:
迭代器遍历用时:
6505100纳秒
索引遍历用时:
4729700纳秒
for-earch遍历用时:
8569100纳秒Process finished with exit code 0
LinkedList
- 以双向链表实现的列表,不支持同步
- 可被当作堆栈、队列和双端队列进行操作
- 顺序访问高效、随机访问较差、中间插入和删除高效
- 适用于经常变化的数据
public static void main(String[] args) {
LinkedList<Integer> list = new LinkedList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
list.add(6);
// 在头部增加9
list.addFirst(9);
// 将10插入到第四个元素,四以后的元素往后挪
list.add(3, 10);
// 将第四个元素删除
list.remove(3);
System.out.println(list.size());
}
遍历性能测试
public static void main(String[] args) {
LinkedList<Integer> list = new LinkedList<>();
for (int i = 0; i < 100000; i++) {
list.add(i);
}
// 使用迭代器遍历
traverseByIterator(list);
// 使用位置索引遍历
traverseByIndex(list);
// 使用for-earch遍历
traverseByFor(list);
}
private static void traverseByFor(LinkedList<Integer> list) {
long startTime = System.nanoTime();
for (Integer integer : list) {
;
}
long endTime = System.nanoTime();
System.out.println("for-earch遍历用时:");
System.out.println((endTime - startTime) + "纳秒");
}
private static void traverseByIndex(LinkedList<Integer> list) {
long startTime = System.nanoTime();
for (int i = 0; i < list.size(); i++) {
list.get(i);
}
long endTime = System.nanoTime();
System.out.println("位置索引用时:");
System.out.println((endTime - startTime) + "纳秒");
}
private static void traverseByIterator(LinkedList<Integer> list) {
long startTime = System.nanoTime();
Iterator<Integer> interator = list.iterator();
while (interator.hasNext()) {
interator.next();
}
long endTime = System.nanoTime();
System.out.println("迭代器遍历用时:");
System.out.println((endTime - startTime) + "纳秒");
}
运行结果:
迭代器遍历用时:
6294100纳秒
位置索引用时:
3135172200纳秒
for-earch遍历用时:
6656100纳秒
Vector
- 和ArrayList类似,可变数组实现的列表
- Vector同步,适合在多线程下使用
- 官方文档建议在非同步情况下,优先采用ArrayList
public static void main(String[] args) {
Vector<Integer> vector = new Vector<>();
vector.add(1);
vector.add(2);
vector.add(3);
vector.add(4);
vector.add(1,3);
System.out.println(vector.size());
}
遍历性能测试
public static void main(String[] args) {
Vector<Integer> vector = new Vector<>();
for (int i = 0; i < 100000; i++) {
vector.add(i);
}
// 使用迭代器遍历
traverseByIterator(vector);
// 使用位置索引遍历
traverseByIndex(vector);
// 使用for-earch遍历
traverseByFor(vector);
}
private static void traverseByFor(Vector<Integer> list) {
long startTime = System.nanoTime();
for (Integer integer : list) {
;
}
long endTime = System.nanoTime();
System.out.println("for-earch遍历用时:");
System.out.println((endTime - startTime) + "纳秒");
}
private static void traverseByIndex(Vector<Integer> list) {
long startTime = System.nanoTime();
for (int i = 0; i < list.size(); i++) {
list.get(i);
}
long endTime = System.nanoTime();
System.out.println("位置索引用时:");
System.out.println((endTime - startTime) + "纳秒");
}
private static void traverseByIterator(Vector<Integer> list) {
long startTime = System.nanoTime();
Iterator<Integer> interator = list.iterator();
while (interator.hasNext()) {
interator.next();
}
long endTime = System.nanoTime();
System.out.println("迭代器遍历用时:");
System.out.println((endTime - startTime) + "纳秒");
}
运行结果:
迭代器遍历用时:
7155600纳秒
位置索引用时:
6508500纳秒
for-earch遍历用时:
6303000纳秒
集合Set
- 确定性:对任意对象都能判定其是否属于某个集合
- 互异性:集合内每个元素都是不相同的,(内容互异)
- 无序性:集合内的顺序无关
- Java中的集合接口Set
- HashSet (基于散列函数的集合,无序,不支持同步)
- TreeSet (基于树结构的集合,可排序的、不支持同步)
- LinkedHashSet(基于散列函数和双向链表的集合,可排序,不支持同步)
HashSet
- 基于HashMap实现的,可容纳null元素,不支持同步
- 支持同步使用 Set set = Collections.synchronizedSet(new HashSet(…))
- add 添加一个元素
- clear 清除整个HashSet
- contains 判定是否包含一个元素
- remove 删除一个元素
- retainAll 计算两个集合交集
public static void main(String[] args) {
HashSet<Integer> hashSet = new HashSet<>();
hashSet.add(null);
hashSet.add(10);
hashSet.add(9);
hashSet.add(8);
hashSet.add(7);
hashSet.add(6);
// 由于以下元素重复所以插入到集合中无效
hashSet.add(6);
hashSet.add(null);
System.out.println("HashSet size is " + hashSet.size()); // 6
System.out.println(hashSet);
// 移除元素6
hashSet.remove(6);
System.out.println(hashSet);
}
运行结果:
HashSet size is 6
[null, 6, 7, 8, 9, 10]
[null, 7, 8, 9, 10]
遍历性能测试:
public static void main(String[] args) {
HashSet<Integer> hashSet = new HashSet<>();
for (int i = 0; i < 10000; i++) {
hashSet.add(i);
}
traverseByIterator(hashSet);
traverseByFor(hashSet);
}
private static void traverseByFor(HashSet<Integer> hashSet) {
long startTime = System.nanoTime();
for (Integer item : hashSet) {
;
}
long endTime = System.nanoTime();
System.out.println("for-earch遍历: ");
System.out.println((endTime - startTime) + "纳秒");
}
private static void traverseByIterator(HashSet<Integer> hashSet) {
long startTime = System.nanoTime();
Iterator<Integer> integerIterator = hashSet.iterator();
while (integerIterator.hasNext()) {
integerIterator.next();
}
long endTime = System.nanoTime();
System.out.println("迭代器遍历: ");
System.out.println((endTime - startTime) + "纳秒");
}
运行结果:
迭代器遍历:
1592900纳秒
for-earch遍历:
1032800纳秒
LinkedHashSet
- 继承HashSet,也是基于HashMap实现的,可容纳null元素
- 不支持同步
- Set set = Collections.synchronizedSet(new LinkedHashSet(…))
- 方法和HashSet基本一致
- add、clear、contains、remove、size
- 通过一个双向链表维护插入顺序
public static void main(String[] args) {
LinkedHashSet<Integer> integers = new LinkedHashSet<>();
integers.add(null);
integers.add(1);
integers.add(2);
integers.add(3);
// 以下重复元素插入无效
integers.add(3);
integers.add(null);
System.out.println(integers.size()); // 4
}
遍历性能测试:
public static void main(String[] args) {
LinkedHashSet<Integer> integers = new LinkedHashSet<>();
for (int i = 0; i < 10000; i++) {
integers.add(i);
}
traverseByIterator(integers);
traverseByFor(integers);
}
private static void traverseByFor(LinkedHashSet<Integer> hashSet) {
long startTime = System.nanoTime();
for (Integer item : hashSet) {
;
}
long endTime = System.nanoTime();
System.out.println("for-earch遍历: ");
System.out.println((endTime - startTime) + "纳秒");
}
private static void traverseByIterator(LinkedHashSet<Integer> hashSet) {
long startTime = System.nanoTime();
Iterator<Integer> integerIterator = hashSet.iterator();
while (integerIterator.hasNext()) {
integerIterator.next();
}
long endTime = System.nanoTime();
System.out.println("迭代器遍历: ");
System.out.println((endTime - startTime) + "纳秒");
}
TreeSet
- TreeSet基于ThreeMap实现的,不可以容纳null元素,不支持同步
- SortedSet set = Collections.synchronizedSortedSet(new TreeSet(…));
- add 添加一个元素
- clear 清空
- contains 判定是否包含一个元素
- remove 删除一个元素
- 根据compareTo方法或Comparator排序
public static void main(String[] args) {
TreeSet<Integer> treeSet = new TreeSet<>();
treeSet.add(100);
treeSet.add(10);
treeSet.add(1);
treeSet.add(12);
treeSet.add(13);
// 默认从小到大排序,输出为[1, 10, 12, 13, 100]
System.out.println(treeSet);
}
遍历性能测试:
public static void main(String[] args) {
TreeSet<Integer> treeSet = new TreeSet<>();
for (int i = 0; i < 10000; i++) {
treeSet.add(i);
}
traverseByIterator(treeSet);
traverseByFor(treeSet);
}
private static void traverseByFor(TreeSet<Integer> hashSet) {
long startTime = System.nanoTime();
for (Integer item : hashSet) {
;
}
long endTime = System.nanoTime();
System.out.println("for-earch遍历: ");
System.out.println((endTime - startTime) + "纳秒");
}
private static void traverseByIterator(TreeSet<Integer> hashSet) {
long startTime = System.nanoTime();
Iterator<Integer> integerIterator = hashSet.iterator();
while (integerIterator.hasNext()) {
integerIterator.next();
}
long endTime = System.nanoTime();
System.out.println("迭代器遍历: ");
System.out.println((endTime - startTime) + "纳秒");
}
运行结果:
迭代器遍历:
2478900纳秒
for-earch遍历:
1279300纳秒
集合注意事项
HashSet、LinkedHashSet和TreeSet
- HashSet,LinkedHashSet和TreeSet的元素只能是对象
- HashSet和LinkedHashSet判定元素重复的原则
- 判定两个元素的hashCode返回值是否相同,若不同,返回false
- 若两者hashCode相同,判定equals方法,若不同,返回false,否则返回ture
TreeSet判定元素重复的原则
- 需要元素继承自Compareble接口
- 比较两个元素的compareTo方法
public class Demo5 {
public static void main(String[] args) {
HashSet<Cat> hashSet = new HashSet<>();
hashSet.add(new Cat(1));
hashSet.add(new Cat(2));
// 由于没有重写hashCode和equals方法所以以下元素没有判定重复
hashSet.add(new Cat(3));
hashSet.add(new Cat(3));
System.out.println(hashSet.size()); // 4
}
}
class Cat {
private int size;
public Cat(int size) {
this.size = size;
}
public int getSize() {
return size;
}
}
以size作为元素重复的判定依据
public class Demo5 {
public static void main(String[] args) {
HashSet<Cat> hashSet = new HashSet<>();
hashSet.add(new Cat(1));
hashSet.add(new Cat(2));
hashSet.add(new Cat(3));
hashSet.add(new Cat(3));
System.out.println(hashSet.size()); // 3
}
}
class Cat {
private int size;
public Cat(int size) {
this.size = size;
}
public int getSize() {
return size;
}
@Override
public boolean equals(Object o) {
// 相同的对象返回ture
if (this == o) return true;
// 不相同类型返回ture
if (o == null || getClass() != o.getClass()) return false;
Cat cat = (Cat) o;
return size == cat.size;
}
@Override
public int hashCode() {
return Objects.hash(size);
}
@Override
public String toString() {
return "Cat{" +java
"size=" + size +
'}';
}
}
注意:HashSet元素判定规则只与hashCode、equals方法有关,和compareTo方法无关
compareTo方法具体规则
// 如果a>0,则obj1>obj2
// 如果a==0,则obj1==obj2
// 如果a<0,则obj1<obj2
int a = obj1.compareTo(obj2);
映射Map
- 映射Map指的是两个集合之间的元素对应关系
- 如 { 1, “张三” } -> { key, value }
Java中的Map
- Hashtable (同步,性能低效,适用于数据量小的场景)
- HashMap (不支持同步,性能高效,适用于数据量大的场景)
- Properties (同步,文件形式,适用于数据量小的场景)
Hashtable
- key-value对,key和value都不允许为null
- 同步,多线程安全
- 无序的
- 适合数据量小
- 主要方法: clear 、contains / containsValue , containsKey , get , put , remove , size
public static void main(String[] args) {
Hashtable<Integer, String> hashtable = new Hashtable<>();
hashtable.put(1, "value 1");
hashtable.put(2, "value 2");
hashtable.put(3, "value 3");
// 输出{3=value 3, 2=value 2, 1=value 1}
System.out.println(hashtable);
}
遍历性能测试:
public static void main(String[] args) {
Hashtable<Integer, String> hashtable = new Hashtable<>();
for (int i = 0; i < 10000; i++) {
hashtable.put(i, "test");
}
// 根据Entry遍历
traverseByEntry(hashtable);
// 根据KeySet遍历
traverseByKeySet(hashtable);
// 根据Enmueration遍历
traverseByKeyEnumeration(hashtable);
}
// Enumeration接口遍历只能读取不能做其他操作
private static void traverseByKeyEnumeration(Hashtable<Integer, String> hashtable) {
long startTime = System.nanoTime();
Integer key;
String value;
Enumeration<Integer> keys = hashtable.keys();
while (keys.hasMoreElements()) {
key = keys.nextElement();
value = hashtable.get(key);
}
long endTime = System.nanoTime();
System.out.println("使用Enumeraton遍历:");
System.out.println((endTime - startTime) + "纳秒");
}
private static void traverseByKeySet(Hashtable<Integer, String> hashtable) {
long startTime = System.nanoTime();
Integer key;
String value;
Iterator<Integer> integerIterator = hashtable.keySet().iterator();
while (integerIterator.hasNext()) {
// 获取key
key = integerIterator.next();
// 获取value
value = hashtable.get(key);
}
long endTime = System.nanoTime();
System.out.println("使用KeySet遍历:");
System.out.println((endTime - startTime) + "纳秒");
}
private static void traverseByEntry(Hashtable<Integer, String> hashtable) {
long startTime = System.nanoTime();
Integer key;
String value;
Iterator<Map.Entry<Integer, String>> iterator = hashtable.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Integer, String> entry = iterator.next();
// 获取key
key = entry.getKey();
// 获取value
value = entry.getValue();
}
long endTime = System.nanoTime();
System.out.println("使用Entry遍历:");
System.out.println((endTime - startTime) + "纳秒");
}
运行结果:
使用Entry遍历:
2537100纳秒
使用KeySet遍历:
1931300纳秒
使用Enumeraton遍历:
1332600纳秒
HashMap
- key-value , key和value都允许为null
- Map map = Collections.synichronizedMap(new HashMap(…));
- 不同步,多线程不安全
- 无序的
- 主要方法: clear , containsValue, containsKey , get , put , remove , size
public static void main(String[] args) {
HashMap<Integer, String> hashMap = new HashMap<>();
hashMap.put(1, null);
hashMap.put(null, "value is null");
hashMap.put(2, "value is two");
// 输出为{null=value is null, 1=null, 2=value is two}
System.out.println(hashMap);
}
遍历性能测试:
public static void main(String[] args) {
HashMap<Integer, String> hashMap = new HashMap<>();
for (int i = 0; i < 100000; i++) {
hashMap.put(i, "test");
}
traverseByEntry(hashMap);
traverseByKeySet(hashMap);
}
private static void traverseByKeySet(HashMap<Integer, String> hashtable) {
long startTime = System.nanoTime();
Integer key;
String value;
Iterator<Integer> integerIterator = hashtable.keySet().iterator();
while (integerIterator.hasNext()) {
// 获取key
key = integerIterator.next();
// 获取value
value = hashtable.get(key);
}
long endTime = System.nanoTime();
System.out.println("使用KeySet遍历:");
System.out.println((endTime - startTime) + "纳秒");
}
private static void traverseByEntry(HashMap<Integer, String> hashtable) {
long startTime = System.nanoTime();
Integer key;
String value;
Iterator<Map.Entry<Integer, String>> iterator = hashtable.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Integer, String> entry = iterator.next();
// 获取key
key = entry.getKey();
// 获取value
value = entry.getValue();
}
long endTime = System.nanoTime();
System.out.println("使用Entry遍历:");
System.out.println((endTime - startTime) + "纳秒");
}
运行结果:
使用Entry遍历:
13562900纳秒
使用KeySet遍历:
11260300纳秒
LinkedHashMap
基于双向链表的维持插入顺序的HashMap
public static void main(String[] args) {
LinkedHashMap<Integer, String> linkedHashMap = new LinkedHashMap<>();
linkedHashMap.put(null, "key is null");
linkedHashMap.put(1, null);
linkedHashMap.put(2, "key is two");
// 输出{null=key is null, 1=null, 2=key is two}
System.out.println(linkedHashMap);
}
遍历性能测试:
public static void main(String[] args) {
LinkedHashMap<Integer, String> linkedHashMap = new LinkedHashMap<>();
for (int i = 0; i < 100000; i++) {
linkedHashMap.put(i, "test");
}
traverseByEntry(linkedHashMap);
traverseByKeySet(linkedHashMap);
}
private static void traverseByKeySet(LinkedHashMap<Integer, String> hashtable) {
long startTime = System.nanoTime();
Integer key;
String value;
Iterator<Integer> integerIterator = hashtable.keySet().iterator();
while (integerIterator.hasNext()) {
// 获取key
key = integerIterator.next();
// 获取value
value = hashtable.get(key);
}
long endTime = System.nanoTime();
System.out.println("使用KeySet遍历:");
System.out.println((endTime - startTime) + "纳秒");
}
private static void traverseByEntry(LinkedHashMap<Integer, String> hashtable) {
long startTime = System.nanoTime();
Integer key;
String value;
Iterator<Map.Entry<Integer, String>> iterator = hashtable.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Integer, String> entry = iterator.next();
// 获取key
key = entry.getKey();
// 获取value
value = entry.getValue();
}
long endTime = System.nanoTime();
System.out.println("使用Entry遍历:");
System.out.println((endTime - startTime) + "纳秒");
}
运行结果:
使用Entry遍历:
9421600纳秒
使用KeySet遍历:
9117500纳秒
TreeMap
基于红黑树的Map,可以根据key的自然排序或者compareTo方法进行排序输出
public static void main(String[] args) {
TreeMap<Integer, String> treeMap = new TreeMap<>();
treeMap.put(2, null);
// 当key为null的时候运行报空指针异常
// treeMap.put(null, "key is null");
treeMap.put(1, "key is two");
// 输出为{1=null, 2=key is two}
System.out.println(treeMap);
}
遍历性能测试:
public static void main(String[] args) {
TreeMap<Integer, String> treeMap = new TreeMap<>();
for (int i = 0; i < 10000; i++) {
treeMap.put(i, "test");
}
traverseByEntry(treeMap);
traverseByKeySet(treeMap);
}
private static void traverseByKeySet(TreeMap<Integer, String> hashtable) {
long startTime = System.nanoTime();
Integer key;
String value;
Iterator<Integer> integerIterator = hashtable.keySet().iterator();
while (integerIterator.hasNext()) {
// 获取key
key = integerIterator.next();
// 获取value
value = hashtable.get(key);
}
long endTime = System.nanoTime();
System.out.println("使用KeySet遍历:");
System.out.println((endTime - startTime) + "纳秒");
}
private static void traverseByEntry(TreeMap<Integer, String> hashtable) {
long startTime = System.nanoTime();
Integer key;
String value;
Iterator<Map.Entry<Integer, String>> iterator = hashtable.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Integer, String> entry = iterator.next();
// 获取key
key = entry.getKey();
// 获取value
value = entry.getValue();
}
long endTime = System.nanoTime();
System.out.println("使用Entry遍历:");
System.out.println((endTime - startTime) + "纳秒");
}
运行结果:
使用Entry遍历:
3187900纳秒
使用KeySet遍历:
4659400纳秒
Properties
- 继承于Hashtable
- 可以将key-value存储到文件中
- 适用于数据量少的配置文件
- 继承自Hashtable的方法:clear , contains / containsValue , containsKey , get , put , remove , size
- 从文件加载的load方法 , 写入到文件的store方法
- 获取属性 getProperty , 设置属性 setProperty
public static void main(String[] args){
System.out.println("写入到Test.properties文件中");
WriteProperties("Test.properties", "name", "123456");
System.out.println("加载到Test.properties文件");
GetAllProperties("Test.properties");
System.out.println("从Test.properties文件加载");
String value = GetValueByKey("Test.properties", "name");
System.out.println("name is " + value);
}
/**
* @param filePath 读取properteis文件名
* @param key 需要读取的key值
* @return String 返回key对应的value
* */
private static String GetValueByKey(String filePath, String key) {
Properties properties = new Properties();
try (InputStream in = new BufferedInputStream(new FileInputStream(filePath))) {
// 加载所有的key-value
properties.load(in);
String value = properties.getProperty(key);
return value;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
/**
* @param filePath 读取properties文件名
* @return void
* */
private static void GetAllProperties(String filePath) {
Properties properties = new Properties();
try (InputStream in = new BufferedInputStream(new FileInputStream(filePath))) {
// 加载所有的key-value
properties.load(in);
// 获取配置文件的名字
Enumeration enumeration = properties.propertyNames();
while (enumeration.hasMoreElements()) {
String strKey = (String) enumeration.nextElement();
String strValue = (String) properties.getProperty(strKey);
System.out.println(strKey + " : " + strValue);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @param filePath 写入properties文件名
* @param key 写入properties文件的key值
* @param value 写入properties文件的value值
* @return void
* */
private static void WriteProperties(String filePath, String key, String value) {
File file = new File(filePath);
boolean fileDoesNotExists = ! file.exists();
if (fileDoesNotExists) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
Properties properties = new Properties();
try (InputStream in = new FileInputStream(filePath)) {
// 加载指定文件
properties.load(in);
OutputStream out = new FileOutputStream(filePath);
properties.setProperty(key, value);
properties.store(out, "update " + key + " name");
} catch (Exception e) {
e.printStackTrace();
}
}
运行结果:
写入到Test.properties文件中
加载到Test.properties文件
name : 123456
从Test.properties文件加载
name is 123456
Test.properties文件中的内容
#update name name
#Sun Jun 13 22:27:45 CST 2021
name=123456
数据结构的工具类
JCF中工具类
- 不存储数据,而是在数据容器上,实现高效操作
- 排序、搜索
- 工具类有:Arrays类、Collections类
Arrays类
- 处理对象是数组
- 排序:对数组排序,sort / parallelSort
- 查找:从数组中查找一个元素,binarySearch
- 批量拷贝:从源数组批量复制到目标数组,copyOf
- 批量复制:对数组进行批量复制,fill
- 判定两个数组内容是否相同,equals
public static void main(String[] args) {
Random random = new Random();
int[] array = new int[10];
for (int i = 0; i < array.length; i++) {
array[i] = random.nextInt() % 100;
}
System.out.println("排序前");
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + ",");
}
System.out.println();
System.out.println("排序后");
Arrays.sort(array);
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + ",");
}
}
运行结果:
排序前
46,12,-95,95,-62,9,92,-44,-14,91,
排序后
-95,-62,-44,-14,9,12,46,91,92,95,
public static void main(String[] args) {
Random random = new Random();
int[] array = new int[10];
for (int i = 0; i < array.length; i++) {
array[i] = random.nextInt() % 100;
}
array[array.length - 1] = 999;
// 当数组中有多个999的时候随机返回999的指定位置
System.out.println("999的位置: " + Arrays.binarySearch(array, 999));
}
运行结果:
999的位置: 9
public static void main(String[] args) {
int[] a = new int[10];
Arrays.fill(a, 100);
int[] b = new int[10];
Arrays.fill(b, 100);
System.out.println("两个数组内容是否相同: " + Arrays.equals(a, b));
}
运行结果:
两个数组内容是否相同: true
Collections类
- Collections处理对象是Collection及其子类
- 排序:对List进行排序,sort
- 搜索:从List中搜索元素,binarySearch
- 批量赋值:对List批量赋值,fill
- 最大、最小:查找集合中最大 / 最小,max,min
- 反序:将List反序排列,reverse
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(12);
list.add(2);
list.add(9);
// 排序
Collections.sort(list);
// 检索
System.out.println("12元素所在的位置: " + Collections.binarySearch(list, 12));
// 最大最小值
System.out.println("最大值: " + Collections.max(list));
System.out.println("最小值: " + Collections.min(list));
// 反序
Collections.reverse(list);
System.out.println("list的反序: " + list);
}
运行结果:
12元素所在的位置: 3
最大值: 12
最小值: 1
list的反序: [12, 9, 2, 1]
对象的比较
- 对象实现Comparable接口(需要修改对象类)
- Arrays和Collections在进行对象sort时,自动调用该方法
- compareTo方法 int a = obj1.compareTo(obj2);
- obj1 > obj2 升序,obj1 < obj2 降序,obj1 == obj2相等
- 新建Comparator(适用于对象类不可更改的情况)
- compare方法 int compare(Person o1, Person o2);
- o1 - o2 > 0 升序,o1 - o2 = 0 相等,o1 - o2 < 0 降序
- Comparator比较器将作为参数提交给工具类的sort方法
public class Demo9 {
public static void main(String[] args) {
Person[] people = new Person[]{
new Person(12), new Person(20), new Person(10)
};
Arrays.sort(people);
for (int i = 0; i < people.length; i++) {
System.out.println(people[i]);
}
}
}
class Person implements Comparable<Person> {
private int age;
public Person(int age) {
this.age = age;
}
@Override
public int compareTo(Person o) {
return this.age - o.age;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
'}';
}
}
运行结果
Person{age=10}
Person{age=12}
Person{age=20}
public class Demo9 {
public static void main(String[] args) {
Person[] people = new Person[]{
new Person(12), new Person(20), new Person(10)
};
// 使用PersonComparator比较器
Arrays.sort(people, new PersonComparator());
for (int i = 0; i < people.length; i++) {
System.out.println(people[i]);
}
}
}
class PersonComparator implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge() - o2.getAge();
}
}
class Person{
private int age;
public Person(int age) {
this.age = age;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
'}';
}
}
运行结果:
Person{age=10}
Person{age=12}
Person{age=20}