JCF
-容器框架:为表示和操作容器而规定的一种标准体系结构
-对外的接口:容器中所能存放的抽象数据类型
-接口的实现:可复用的数据结构
-算法:对数据的查找和排序容器框架优点:提高数据存取效率,避免程序员重复劳动
JCF的集合接口是Collection(List,Set,Map)
-add,contains,remove,size
-iterator
JCF的迭代器接口Iterator
-hasNext判断是否有下一个元素
-next获取下一个元素
-remove删除某一个元素
JCF主要的数据结构实现类
-列表(List, ArrayLis, LinkedList)
-集合(Set, HashSet, TreeSet, LinkedHashSet)
-映射(Map, HashMap, TreeMap, LinkedHashMap)
JCF主要的算法类
-Arrays:对数组进行查找和排序等操作
-Collections: 对Collection及其子类进行排序和查找操作
列表List
-有序的Collection
-允许重复元素
-{1, 2, 4, {5, 2}, 1, 3}
List主要实现
-ArrayList(非同步的)
-LinkedList(非同步)
-Vector(同步)
ArrayList
-以数组实现的列表,不支持同步
-利用索引位置可以快速定位访问
-不适合指定位置的插入、删除操作
-适合变动不大,主要用于查询的数据
-和Java数组相比,其容量是可动态调整的
-ArrayList在元素填满容器时会自动扩充容器大小的50%
ArrayList只能装对象
创建
import java.util.ArrayList;
import java.util.Iterator;
public class ArrayListTest {
public static void main(String[] a) {
ArrayList<Integer> al = new ArrayList<Integer>(); //<Integer>表示泛型,说明al这个ArrayList里只能存放Integer这个类型的数据
al.add(3);
//自动将普通的int变量3自动装箱为Integer(3)的对象,然后放入al里
al.add(2);
al.add(1);
al.add(4);
al.add(5);
al.add(6);
al.add(new Integer(6));
System.out.print("The third element is ");
System.out.println(al.get(3));//获得第四个元素
al.remove(3); //删除第四个元素,后面元素往前挪动
al.add(3, 9); //将9插入到第4个元素,后面元素往后挪动
输出
The third element is 4
遍历方法
创建ArrayList
ArrayList<Integer> as = new ArrayList<Integer>(100000);//创建了包含100000个数据的ArrayList
for (int i=0; i<100000; i++)
{
as.add(i);
}
traverseByIterator(as); //iteration遍历,如下
traverseByIndex(as); //索引位置遍历,如下
traverseByFor(as); //for-each遍历,如下
}
iteration遍历
public static void traverseByIterator(ArrayList<Integer> al)
{
Iterator<Integer> iter1 = al.iterator();
while(iter1.hasNext())
{
iter1.next();
}
}
索引位置遍历
public static void traverseByIndex(ArrayList<Integer> al)
{
for(int i=0;i<al.size();i++)
{
al.get(i);
}
}
for循环遍历
public static void traverseByFor(ArrayList<Integer> al)
{
for(Integer item : al)
{
; //任意语句
}
}
迭代器的速度最慢,索引方法和for方法速度接近
LinkedList
-以双向链表实现的列表,不支持同步
-可被当作堆栈、队列和双端队列进行操作
-顺序访问高效,随机访问较差,中间插入和删除高效
-适用于经常变化的数据
创建
import java.util.Iterator;
import java.util.LinkedList;
public class LinkedListTest {
public static void main(String[] args) {
LinkedList<Integer> ll = new LinkedList<Integer>();
ll.add(3);
ll.add(2);
ll.add(5);
ll.add(6);
ll.add(6);
System.out.println(ll.size()); //输出5
ll.addFirst(9); //在头部增加9
ll.add(3, 10); //将10插入到第四个元素,四以及后续的元素往后挪动
ll.remove(3); //将第四个元素删除
遍历方法
创建LinkedList
LinkedList<Integer> list = new LinkedList<Integer>();
for (int i=0; i<100000; i++)
{
list.add(i);
}
traverseByIterator(list); //iteration遍历,如下
traverseByIndex(list); //索引位置遍历,如下
traverseByFor(list); //for-each遍历,如下
}
iteration遍历
public static void traverseByIterator(LinkedList<Integer> list)
{
Iterator<Integer> iter1 = list.iterator();
while(iter1.hasNext())
{
iter1.next();
}
}
索引位置遍历
public static void traverseByIndex(LinkedList<Integer> list)
{
for(int i=0;i<list.size();i++)
{
list.get(i);
}
}
for循环遍历
public static void traverseByFor(LinkedList<Integer> list)
{
for(Integer item : list)
{
; //任何语句
}
}
for循环遍历比迭代器快一点点,索引遍历最慢
ArrayList适用于较多查询的静态数据,而LinkedList适用于频繁增删的数据
Vector
-和ArrayList类似,可变数组实现的列表
-Vectora,适合在多线程下使用
-官方文档建议在非同步情况下,优先采用ArrayList
创建
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;
public class VectorTest {
public static void main(String[] args) {
Vector<Integer> v = new Vector<Integer>();
v.add(1);
v.add(2);
v.add(3);
v.remove(2);
v.add(1, 5);
System.out.println(v.size());
遍历方法
创建一个Vector
Vector<Integer> v2 = new Vector<Integer>(100000);
for (int i = 0; i < 100000; i++) {
v2.add(i);
}
traverseByIterator(v2);//itertor遍历
traverseByIndex(v2);//索引位置遍历
traverseByFor(v2);//for-each遍历
traverseByEnumeration(v2);//Enumeration遍历
}
iterator遍历
public static void traverseByIterator(Vector<Integer> v) {
Iterator<Integer> iter1 = v.iterator();
while (iter1.hasNext())
{
iter1.next();
}
}
索引位置遍历
public static void traverseByIndex(Vector<Integer> v) {
for (int i = 0; i < v.size(); i++)
{
v.get(i);
}
}
for循环遍历
public static void traverseByFor(Vector<Integer> v) {
for (Integer item : v)
{
; //任意语句
}
}
Enumeration遍历(老方法)
public static void traverseByEnumeration(Vector<Integer> v) {
for (Enumeration<Integer> enu = v.elements();enu.hasMoreElements();){
enu.nextElement();
}
}
for循环最快,其次是位置索引
Set集合
-确定性:对任意对象都能判定其是否属于某一个集合
-互异性:集合内每个元素都是无差异的,注意是内容差异
-无序性:集合内的顺序无关
Java中的集合接口Set
-HashSet (基于散列函数的集合,无序,不支持同步)
-TreeSet (基于树结构的集合,可排序的,不支持同步)
-LinkedHashSet(基于散列函数和双向链表的集合,可排序的,不支持同步)
HashSet
-基于HashMap实现的,可以容纳null元素,不支持同步
-add添加一个元素
-clear清除整个HashSet
-contains判定是否包含一个元素
-remove删除一个元素
-size大小
-retainAll计算两个集合交集
创建
import java.util.HashSet;
import java.util.Iterator;
public class HashSetTest {
public static void main(String[] args) {
HashSet<Integer> hs = new HashSet<Integer>();
hs.add(null);
hs.add(1000);
hs.add(20);
hs.add(3);
hs.add(40000);
hs.add(5000000);
hs.add(3); //3 重复
hs.add(null); //null重复
System.out.println(hs.size()); //6
if(!hs.contains(6))
{
hs.add(6);
}
System.out.println(hs.size()); //7
hs.remove(4);
System.out.println(hs.size()); //6
hs.clear();
System.out.println(hs.size()); //0
集合交集
HashSet<String> set1 = new HashSet<String>();
HashSet<String> set2 = new HashSet<String>();
set1.add("a");
set1.add("b");
set1.add("c");
set2.add("c");
set2.add("d");
set2.add("e");
set1.retainAll(set2);
//set1的元素不在set2里面的全部被删除,那么set1只剩一个元素c
System.out.println("交集是 "+set1); //输出c
遍历方法
创建Set
HashSet<Integer> hs2 = new HashSet<Integer>();
for(int i=0;i<100000;i++)
{
hs2.add(i);
}
traverseByIterator(hs2); //迭代器遍历,如下
traverseByFor(hs2); //for循环遍历,如下
}
迭代器遍历
public static void traverseByIterator(HashSet<Integer> hs)
{
Iterator<Integer> iter1 = hs.iterator();
while(iter1.hasNext())
{
iter1.next();
}
}
for循环遍历
public static void traverseByFor(HashSet<Integer> hs)
{
for(Integer item : hs)
{
; //任意语句
}
}
}
for循环速度比迭代器遍历快
LinkedHashSet
-继承HashSet,也是基于HashMap实现的,可以容纳null元素
-不支持同步
-方法和HashSet基本一致
add, clear, contains, remove, size
-通过一个双向链表维护插入顺序
创建
import java.util.Iterator;
import java.util.LinkedHashSet;
public class LinkedHashSetTest {
public static void main(String[] args) {
LinkedHashSet<Integer> lhs = new LinkedHashSet<Integer>();
lhs.add(null);
lhs.add(1000);
lhs.add(20);
lhs.add(3);
lhs.add(40000);
lhs.add(5000000);
lhs.add(3); //3 重复
lhs.add(null); //null 重复
System.out.println(lhs.size()); //6
if(!lhs.contains(6))
{
lhs.add(6);
}
System.out.println(lhs.size()); //7
lhs.remove(4);
System.out.println(lhs.size()); //6
lhs.clear();
System.out.println(lhs.size()); //0
遍历方法
创建LinkedHashSet
LinkedHashSet<Integer> lhs2 = new LinkedHashSet<Integer>();
for(int i=0;i<100000;i++)
{
lhs2.add(i);
}
traverseByIterator(lhs2);
traverseByFor(lhs2);
}
迭代器遍历
public static void traverseByIterator(LinkedHashSet<Integer> hs)
{
Iterator<Integer> iter1 = hs.iterator();
while(iter1.hasNext())
{
iter1.next();
}
}
for循环遍历
public static void traverseByFor(LinkedHashSet<Integer> hs)
{
for(Integer item : hs)
{
; //任意语句
}
}
LinkedHashSet是保留顺序的,其遍历顺序额插入顺序一致,而HashSet没有保留顺序,其遍历顺序无序
TreeSet
-基于TreeMap实现的,不可以容纳null元素,不支持同步
-add添加一个元素
-clear清除整个TreeSet
-contains判定是否包含一个元素
-remove删除一个元素
-size大小
-根据compareTo方法或指定Comparator排序
创建
import java.util.Iterator;
import java.util.TreeSet;
public class TreeSetTest {
public static void main(String[] args) {
TreeSet<Integer> ts = new TreeSet<Integer>();
// ts.add(null); 错误,不支持null
ts.add(1000);
ts.add(20);
ts.add(3);
ts.add(40000);
ts.add(5000000);
ts.add(3); //3 重复
System.out.println(ts.size()); //5
if(!ts.contains(6))
{
ts.add(6);
}
System.out.println(ts.size()); //6
ts.remove(4);
System.out.println(ts.size()); //5
lhs.clear();
System.out.println(lhs.size()); //0
遍历方法
==TreeSet是按照所存储对象大小升序输出的 ==
创建TreeSet
TreeSet<Integer> ts2 = new TreeSet<Integer>();
for(int i=0;i<100000;i++)
{
ts2.add(i);
}
traverseByIterator(ts2); //迭代器遍历
traverseByFor(ts2); //for循环遍历
}
迭代器遍历
public static void traverseByIterator(TreeSet<Integer> hs)
{
Iterator<Integer> iter1 = hs.iterator();
while(iter1.hasNext())
{
iter1.next();
}
for循环遍历
public static void traverseByFor(TreeSet<Integer> hs)
{
for(Integer item : hs)
{
; //任意语句
}
}
}
判定等价
-HashSet, LinkedHashSet, TreeSet的元素都只能是对象
-HashSet和LinkedHashSet判定元素重复的原则
-判定两个元素的hashCode返回值是否相同,若不同,返回false
-若两者hashCode相同,判定equals方法,若不同,返回false;否则返回true
- hashCode和equals方法是所有类都有的,因为Object类有
-TreeSet判定元素重复的原则
-需要元素继承自Comparable接口
-比较两个元素的compareTo方法
HashSet, LinkedHashSet的例子
创建一个猫的类,只有一个成员变量size
class Cat
{
private int size;
public Cat(int size)
{
this.size = size;
}
}
创建一个HashSet和LinkedHashSet,里面的成员是Cat
import java.util.HashSet;
public class JudgeRuleTest {
public static void main(String[] args) {
HashSet<Cat> hs = new HashSet<Cat>();
hs.add(new Cat(1));
hs.add(new Cat(2));
hs.add(new Cat(3));
hs.add(new Cat(3));
System.out.println(hs.size()); //4
//最后的两只Cat(3),被判定不是相同的变量
LinkedHashSet<Cat> lhs= new LinkedHashSet<Cat>();
lhs.add(new Cat(2));
lhs.add(new Cat(1));
lhs.add(new Cat(3));
lhs.add(new Cat(5));
lhs.add(new Cat(4));
lhs.add(new Cat(4));
System.out.println(lhs.size()); //6
//最后的两只Cat(4),被判定不是相同的变量
}
}
Cat类本身没有hashCode(),而是继承Object类的,而Object的hashCode()会返回对象信息和内存地址经过运算后的一个int值。两个不同的Cat(4)对象,他们的hashCode()返回值是不同的
创建狗的类,成员属性size,重写了hashCode(),equals(),toString()函数
class Dog {
private int size;
public Dog(int s) { ///构造函数
size = s;
}
public int getSize() {
return size;
}
public boolean equals(Object obj2) { //重写Dog自己的equals()函数
if(0==size - ((Dog) obj2).getSize()) {
return true;
} else {
return false;
}
}
public int hashCode() { //重写Dog自己的hashCode()函数
return size;
}
public String toString() {
return size + "";
}
}
创建一个HashSet和LinkedHashSet,里面的成员是Dog
HashSet<Dog> hs2 = new HashSet<Dog>();
hs2.add(new Dog(2));
hs2.add(new Dog(1));
hs2.add(new Dog(3));
hs2.add(new Dog(5));
hs2.add(new Dog(4));
hs2.add(new Dog(4));
System.out.println(hs2.size()); //5
//最后的两只Dog(4),被判定是相同的变量
LinkedHashSet<Dog> lhs2= new LinkedHashSet<Dog>();
lhs2.add(new Dog(2));
lhs2.add(new Dog(1));
lhs2.add(new Dog(3));
lhs2.add(new Dog(5));
lhs2.add(new Dog(4));
lhs2.add(new Dog(4));
System.out.println(lhs2.size()); //5
//最后的两只Dog(4),被判定是相同的变量
Dog类本身改写了hashCode()方法,其返回值是具体的size,所以两个不同Dog(4),他们的hashCode()返回值是相同的
若两者hashCode相同,判定equals方法,若不同,返回false;否则返回true
重写时hashCode,equals,toString最好同时修改
创建Tiger类,包含成员变量size,实现Comparable接口
public class Tiger implements Comparable{
private int size;
public Tiger(int s) {
size = s;
}
public int getSize() {
return size;
}
public int compareTo(Object o) {
return size - ((Tiger) o).getSize();
}
}
Tiger实现Comparable接口,所以必须实现compareTo方法来比较大小。compareTo方法具体规则如下:
int a =obj1. compareTo (obj2);
如果a>0,则obj1>obj2;
如果a= =0;则obj1=obj2;
如果a<0,则obj1<obj2
HashSet<Tiger> hs3 = new HashSet<Tiger>();
hs3.add(new Tiger(2));
hs3.add(new Tiger(1));
hs3.add(new Tiger(3));
hs3.add(new Tiger(5));
hs3.add(new Tiger(4));
hs3.add(new Tiger(4));
System.out.println(hs3.size()); //6
LinkedHashSet<Tiger> lhs3= new LinkedHashSet<Tiger>();
lhs3.add(new Tiger(2));
lhs3.add(new Tiger(1));
lhs3.add(new Tiger(3));
lhs3.add(new Tiger(5));
lhs3.add(new Tiger(4));
lhs3.add(new Tiger(4));
System.out.println(lhs3.size()); //6
}
因为HashSet, LinkedHashSet判断对象是否相同,不根据compareTo
TreeSet的例子
添加到TreeSet的,需要实现Comparable接口,即实现compareTo方法
TreeSet<Tiger> ts3 = new TreeSet<Tiger>();
ts3.add(new Tiger(2));
ts3.add(new Tiger(1));
ts3.add(new Tiger(3));
ts3.add(new Tiger(5));
ts3.add(new Tiger(4));
ts3.add(new Tiger(4));
System.out.println(ts3.size()); //5
}
判断两个Tiger(4)是否相同,会调用compareTo方法,return size - ((Tiger) o).getSize();
表明两个size一样返回0,说明他们是相同的
Map映射
-两个集合之间的元素对应关系
-一个输入对应到一个输出
-{1,张三}, {2,李四}, {Key, Value},键值对, K-V对
Java中Map
-Hashtable (同步,慢, 数据量小)
-HashMap (不支持同步,快,数据量大)
-Properties (同步,文件形式,数据量小)
Hashtable
-K-V对,K和V都不允许为null
-同步,多线程安全
-无序的
-适合小数据量
-主要方法: clear清空数据,contains等同containsValue是否包含某一个值,containsKey是否包含某一个Key,get根据Key获取相应的值,put增加新的K-V对,remove删除某一个K-V对,size返回数据大小
创建
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
public class HashtableTest {
public static void main(String[] args) {
Hashtable<Integer,String> ht =new Hashtable<Integer,String>();
//ht.put(1, null); 编译不报错 运行报错
//ht.put(null,1); 编译报错
ht.put(1000, "aaa");
ht.put(2, "bbb");
ht.put(30000, "ccc");
System.out.println(ht.contains("aaa"));
System.out.println(ht.containsValue("aaa"));
System.out.println(ht.containsKey(30000));
System.out.println(ht.get(30000));
ht.put(30000, "ddd"); //更新覆盖ccc
ht.remove(2);
ht.clear();
遍历方法
创建Hashtable
Hashtable<Integer,String> ht2 =new Hashtable<Integer,String>();
for(int i=0;i<100000;i++)
{
ht2.put(i, "aaa");
}
traverseByEntry(ht2); //Entry迭代器遍历
traverseByKeySet(ht2); //KeySet迭代器遍历
traverseByKeyEnumeration(ht2); //KeyEnumeration迭代器遍历
}
Entry迭代器遍历,Entry是指整个K-V对
public static void traverseByEntry(Hashtable<Integer,String> ht)
{
Integer key;
String value;
Iterator<Entry<Integer, String>> iter = ht.entrySet().iterator();
while(iter.hasNext())
{
Map.Entry<Integer, String> entry = iter.next();
// 获取key
key = entry.getKey();
// 获取value
value = entry.getValue();
}
}
Key的iterator迭代器遍历,可以删除元素
public static void traverseByKeySet(Hashtable<Integer,String> ht)
{
Integer key;
String value;
Iterator<Integer> iter = ht.keySet().iterator();
while(iter.hasNext())
{
key = iter.next();
// 获取value
value = ht.get(key);
}
}
Key的Enumeration迭代器遍历,只读
public static void traverseByKeyEnumeration(Hashtable<Integer,String> ht)
{
Integer key;
String value;
Enumeration<Integer> keys = ht.keys();
while(keys.hasMoreElements())
{
key = keys.nextElement();
// 获取value
value = ht.get(key);
}
}
Entry遍历最慢,Enumeration最快
HashMap
-K-V对, K和V都允许为null
-不同步,多线程不安全
-无序的
-主要方法: clear, containsValue, containsKey, get, put,remove, size
创建
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
public class HashMapTest {
public static void main(String[] args) {
HashMap<Integer,String> hm =new HashMap<Integer,String>();
hm.put(1, null);
hm.put(null, "abc");
hm.put(1000, "aaa");
hm.put(2, "bbb");
hm.put(30000, "ccc");
hm.containsValue("aaa");
hm.containsKey(30000);
hm.get(30000);
hm.put(30000, "ddd"); //更新覆盖ccc
hm.remove(2);
hm.clear();
遍历方法
创建HashMap
HashMap<Integer,String> hm2 =new HashMap<Integer,String>();
for(int i=0;i<100000;i++)
{
hm2.put(i, "aaa");
}
traverseByEntry(hm2); //Entry迭代器遍历
traverseByKeySet(hm2); //KeySet迭代器遍历
}
Entry迭代器遍历
public static void traverseByEntry(HashMap<Integer,String> ht)
{
Integer key;
String value;
Iterator<Entry<Integer, String>> iter = ht.entrySet().iterator();
while(iter.hasNext())
{
Map.Entry<Integer, String> entry = iter.next();
// 获取key
key = entry.getKey();
// 获取value
value = entry.getValue();
}
}
KeySet迭代器遍历
public static void traverseByKeySet(HashMap<Integer,String> ht)
{
Integer key;
String value;
Iterator<Integer> iter = ht.keySet().iterator();
while(iter.hasNext())
{
key = iter.next();
// 获取value
value = ht.get(key);
}
}
LinkedHashMap
-基于双向链表的维持插入顺序的HashMap TreeMap
创建
import java.util.LinkedHashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
public class LinkedHashMapTest {
public static void main(String[] args) {
LinkedHashMap<Integer,String> hm=new LinkedHashMap<Integer,String>();
hm.put(1, null);
hm.put(null, "abc");
hm.put(1000, "aaa");
hm.put(2, "bbb");
hm.put(30000, "ccc");
hm.containsValue("aaa");
hm.containsKey(30000);
hm.get(30000);
hm.put(30000, "ddd"); //更新覆盖ccc
hm.remove(2);
hm.clear();
遍历方法
创建LinkedHashMap
LinkedHashMap<Integer,String> hm2=new LinkedHashMap<Integer,String>();
for(int i=0;i<100000;i++)
{
hm2.put(i, "aaa");
}
traverseByEntry(hm2); //Entry迭代器遍历
traverseByKeySet(hm2); //KeySet迭代器遍历
}
Entry迭代器遍历
public static void traverseByEntry(LinkedHashMap<Integer,String> ht)
{
Integer key;
String value;
Iterator<Entry<Integer, String>> iter = ht.entrySet().iterator();
while(iter.hasNext())
{
Map.Entry<Integer, String> entry = iter.next();
// 获取key
key = entry.getKey();
// 获取value
value = entry.getValue();
}
}
KeySet迭代器遍历
public static void traverseByKeySet(LinkedHashMap<Integer,String> ht)
{
Integer key;
String value;
Iterator<Integer> iter = ht.keySet().iterator();
while(iter.hasNext())
{
key = iter.next();
// 获取value
value = ht.get(key);
//System.out.println("Key:" + key + ", Value:" + value);
}
}
}
TreeMap
-基于红黑树的Map,可以根据key的自然排序或者compareTo方法进行排序输出
创建
import java.util.TreeMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
public class TreeMapTest {
public static void main(String[] args) {
TreeMap<Integer,String> hm =new TreeMap<Integer,String>();
hm.put(1, null);
//hm.put(null, "abc"); 编译没错,运行报空指针异常
hm.put(1000, "aaa");
hm.put(2, "bbb");
hm.put(30000, "ccc");
hm.containsValue("aaa");
hm.containsKey(30000);
hm.get(30000);
hm.put(30000, "ddd"); //更新覆盖ccc
hm.remove(2);
hm.clear();
遍历方法
创建TreeMap
TreeMap<Integer,String> hm2 =new TreeMap<Integer,String>();
for(int i=0;i<100000;i++)
{
hm2.put(i, "aaa");
}
traverseByEntry(hm2); //Entry迭代器遍历
traverseByKeySet(hm2); //KeySet迭代器遍历
}
Entry迭代器遍历
public static void traverseByEntry(TreeMap<Integer,String> ht)
{
Integer key;
String value;
Iterator<Entry<Integer, String>> iter = ht.entrySet().iterator();
while(iter.hasNext())
{
Map.Entry<Integer, String> entry = iter.next();
// 获取key
key = entry.getKey();
// 获取value
value = entry.getValue();
}
}
KeySet迭代器遍历
public static void traverseByKeySet(TreeMap<Integer,String> ht)
{
Integer key;
String value;
Iterator<Integer> iter = ht.keySet().iterator();
while(iter.hasNext())
{
key = iter.next();
// 获取value
value = ht.get(key);
//System.out.println("Key:" + key + ", Value:" + value);
}
}
}
Properties
-继承于Hashtable
-可以将K-V对保存在文件中
-适用于数据量少的配置文件
-从文件加载的load方法, 写入到文件中的store方法
-获取某一个Key所对应的Value用getProperty,写入一个K-V对用setProperty
-如需要将 K-V 存储为文件,可采用 Properties 类
常规操作
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Properties;
//关于Properties类常用的操作
public class PropertiesTest {
public static String GetValueByKey(String filePath, String key) {
Properties pps = new Properties();
try {
InputStream in = new BufferedInputStream (new FileInputStream(filePath));
pps.load(in); //所有的K-V对都加载了
String value = pps.getProperty(key); //根据Key读取Value
return value;
}catch (IOException e) {
e.printStackTrace();
return null;
}
}
写入
//写入Properties信息
public static void WriteProperties (String filePath, String pKey, String pValue) throws IOException {
File file = new File(filePath);
if(!file.exists())
{
file.createNewFile();
}
Properties pps = new Properties();
InputStream in = new FileInputStream(filePath);
//从输入流中读取属性列表(键和元素对)
pps.load(in);
//调用 Hashtable 的方法 put。使用 getProperty 方法提供并行性。
//强制要求为属性的键和值使用字符串。返回值是 Hashtable 调用 put 的结果。
OutputStream out = new FileOutputStream(filePath);
pps.setProperty(pKey, pValue);
//以适合使用 load 方法加载到 Properties 表中的格式,
//将此 Properties 表中的属性列表(键和元素对)写入输出流
pps.store(out, "Update " + pKey + " name");
out.close();
}
读取
//读取Properties的全部信息
public static void GetAllProperties(String filePath) throws IOException {
Properties pps = new Properties();
InputStream in = new BufferedInputStream(new FileInputStream(filePath));
pps.load(in); //所有的K-V对都加载了
Enumeration en = pps.propertyNames(); //得到文件的名字
while(en.hasMoreElements()) {
String strKey = (String) en.nextElement();
String strValue = pps.getProperty(strKey);
}
}
工具类
JCF中工具类
-不存储数据,而是在数据容器上,实现高效操作
-排序
-搜索
-Arrays 类
-Collections 类
Arrays:处理对象是数组
-排序:对数组排序, sort/parallelSort
-查找:从数组中查找一个元素, binarySearch
-批量拷贝:从源数组批量复制元素到目标数组, copyOf
-批量赋值:对数组进行批量赋值, fill
-等价性比较:判定两个数组内容是否相同, equals
import java.util.Arrays;
import java.util.Random;
public class ArraysTest {
public static void main(String[] args) {
testSort();
testSearch();
testCopy();
testFill();
testEquality();
}
sort()排序
public static void testSort() {
Random r = new Random();
int[] a = new int[10];
for(int i=0;i<a.length;i++) {
a[i] = r.nextInt(); //返回下一个int随机数
}
System.out.println("===============测试排序================");
System.out.println("排序前");
for(int i=0;i<a.length;i++) {
System.out.print(a[i] + ",");
}
System.out.println("排序后");
Arrays.sort(a); //用来排序的函数
for(int i=0;i<a.length;i++) {
System.out.print(a[i] + ",");
}
}
输出
===============排序================
排序前
-956351502,1319671543,514166787,2025415429,1194844482,50373231,591196643,-312467671,672486313,-1919848267,
排序后
-1919848267,-956351502,-312467671,50373231,514166787,591196643,672486313,1194844482,1319671543,2025415429,
binarySearch()查找
public static void testSearch() {
Random r = new Random();
int[] a = new int[10];
for(int i=0;i<a.length;i++)
{
a[i] = r.nextInt();
}
a[a.length-1] = 10000;
System.out.println("===========测试查找============");
System.out.println("10000 的位置是" + Arrays.binarySearch(a, 10000));
}
输出
===========查找============
10000 的位置是-3
copyOf()拷贝
public static void testCopy() {
Random r = new Random();
int[] a = new int[10];
for(int i=0;i<a.length;i++)
{
a[i] = r.nextInt();
}
int[] b = Arrays.copyOf(a, 5);
System.out.println("===========测试拷贝前五个元素============");
System.out.print("源数组:");
for(int i=0;i<a.length;i++)
{
System.out.print(a[i] + ",");
}
System.out.println();
System.out.print("目标数组:");
for(int i=0;i<b.length;i++)
{
System.out.print(b[i] + ",");
}
System.out.println();
}
输出
===========拷贝前五个元素============
源数组:-1978377658,782629928,-1800820484,787311198,1385421194,1893651335,1067858632,1740898767,-1886555356,-884417663,
目标数组:-1978377658,782629928,-1800820484,787311198,1385421194,
fill()批量赋值
public static void testFill() {
int[] a = new int[10];
Arrays.fill(a, 100);
Arrays.fill(a, 2, 8, 200);
System.out.println("===========测试批量赋值============");
System.out.print("数组赋值后:");
for(int i=0;i<a.length;i++)
{
System.out.print(a[i] + ",");
}
System.out.println();
}
输出
===========批量赋值============
数组赋值后:100,100,200,200,200,200,200,200,100,100,
equals()测试
public static void testEquality() {
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));
b[9] = 200;
System.out.println(Arrays.equals(a, b));
}
}
输出
true
false
Collections:处理对象是Collection及其子类,例如Map,Set,List等
-排序:对List进行排序, sort
-搜索:从List中搜索元素, binarySearch
-批量赋值: 对List批量赋值, fill
-最大、最小:查找集合中最大/小值, max, min
-反序:将List反序排列, reverse
mport java.util.ArrayList;
import java.util.Collections;
public class CollectionsTest {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(12);
list.add(2);
list.add(19);
// 排序
Collections.sort(list);
// 检索
System.out.println("元素所在的索引值是:" + Collections.binarySearch(list, 12));
//最大最小
System.out.println("最大值:" + Collections.max(list));
System.out.println("最小值:" + Collections.min(list));
Collections.reverse(list); //翻转不需要用到排序
Collections.fill(list, 100); //全部赋值为100
}
}
输出
元素所在的索引值是:2
最大值:19
最小值:1
对象比较
-对象实现Comparable接口(需要修改对象类)
-compareTo方法
>返回1,
= =返回0,
<返回-1
-Arrays和Collections在进行对象sort时, 自动调用该方法
-新建Comparator (适用于对象类不可更改的情况)
-compare方法
>返回1,
= =返回0,
<返回-1
-Comparator比较器将作为参数提交给工具类的sort方法
对象排序需要遵循一定的规则。
Integor对象可以自然按照数值大小进行排序
而普通的自定义对象无法排序。因此,普通的自定义对象需要实现Comparabl换口,按照 compareTo方法所规定的原则进行排序
例子
普通的自定义对象
import java.util.Arrays;
//person实现接口Comparable,泛型Person
public class Person implements Comparable<Person> {
String name;
int age;
public String getName() {
return name;
}
public int getAge() {
return age;
}
//构造函数
public Person(String name, int age) {
this.name = name;
this.age = age;
}
//实现Comparable里的compareTo函数
public int compareTo(Person another) {
int i = 0;
i = name.compareTo(another.name); // 使用字符串的比较,字符串可以直接使用compareTo
if (i == 0) {
// 如果名字一样,比较年龄, 返回比较年龄结果
return age - another.age;
} else {
return i; // 名字不一样, 返回比较名字的结果.
}
}
public static void main(String... a) {
Person[] ps = new Person[3];
ps[0] = new Person("Tom", 20);
ps[1] = new Person("Mike", 18);
ps[2] = new Person("Mike", 20);
Arrays.sort(ps);
for (Person p : ps) {
System.out.println(p.getName() + "," + p.getAge());
}
}
}
输出
//先对名字排序,再对年纪排序
Mike,18
Mike,20
Tom,20
不可变的对象
假设Person2不可更改
public class Person2 {
private String name;
private int age;
public String getName() {
return name;
}
public int getAge() {
return age;
}
public Person2(String name, int age)
{
this.name = name;
this.age = age;
}
}
创建Person2Comparator实现Comparator接口
import java.util.Arrays;
import java.util.Comparator;
public class Person2Comparator implements Comparator<Person2> {
//实现Comparator里的compare方法
public int compare(Person2 one, Person2 another) {
int i = 0;
i = one.getName().compareTo(another.getName());// 使用字符串的比较,字符串可以直接使用compareTo
if (i == 0) {
// 如果名字一样,比较年龄,返回比较年龄结果
return one.getAge() - another.getAge();
} else {
return i; // 名字不一样, 返回比较名字的结果.
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Person2[] ps = new Person2[3];
ps[0] = new Person2("Tom", 20);
ps[1] = new Person2("Mike", 18);
ps[2] = new Person2("Mike", 20);
Arrays.sort(ps, new Person2Comparator()); //不可变对象的sort参数多了一个创建的Person2Comparator类
for (Person2 p : ps) {
System.out.println(p.getName() + "," + p.getAge());
}
}
}
输出
Mike,18
Mike,20
Tom,20