第一节 数组
数组是一个存放多个数据的容器
- 数据是同一类型
- 所有的数据是线性规则排列
- 可用过位置索引来快速定位访问数据
- 需明确容器的长度
第二节 Java Collection Framework
容器框架:为表示和操作容器而规定的一种标准体系结构
- 对外的接口:容器中所能存放的抽象数据类型
- 接口的实现:可复用的数据结构
- 算法:对数据的查找和排序
容器框架的优点:提高数据存取效率,避免重复劳动
绿色部分是列表-list
黄色部分是散列集合-set
浅蓝色是映射-map
深蓝色-时代久远
JCF的集合接口是Collection:
- add, contains, remove, size
- iterator
JCF的迭代器接口iterator:
- hasNext
- next
- remove
JCF主要的数据结构实现类:
- 列表 (List, ArrayList, LinkedList)
- 集合 (Set, HashSet, TreeSet, LinkedHashSet)
- 映射 (Map, HashMap, TreeMap, LinkedHashMap)
JCF主要的算法类
- Arrays: 对数组进行查找和排序等操作
- Collections:对Collection及其子类进行排序和查找操作
第三节 列表List
List:列表
- 有序的Collection
- 允许重复元素,允许嵌套
- {1, 2, 4, {5, 2}, 1, 3}
List主要实现
- ArrayList, 非同步
- LinkedList,非同步
- Vector,同步
Arraylist:
- 以数组实现的列表,不支持同步
- 利用索引位置可以快速定位访问
- 不适合指定位置的插入,删除操作
- 适合变动不大,主要用于查询的数据
- 和Java数组相比,其容量是可动态调整的
- ArrayList在元素填满容器时会自动扩充容器大小的50%
//Iterator遍历 速度慢
public static void traverseByIterator(ArrayList<Integer> a1){
Iterator<Integer> iter1 = a1.iterator();
while(iter1.hasNext()){
iter1.next();
}
}
//索引遍历 速度中等
public static void traverseByIndex(ArrayList<Integer> a1){
for(int i = 0; i<a1.size(); i++){
a1.get(i);
}
}
//for-each遍历 速度快
public static void traverseByFor(ArrayList<Integer> a1){
for(Integer item : a1){
...;
}
}
LinkedLIst:
- 以双向链表实现的列表,不支持同步
- 可被当作堆栈,队列和双端队列进行操作
- 顺序访问高效,随机访问较差,中间插入和删除高效
- 适用于经常变化的数据
LinkedList的遍历操作(同上):
- Iterator遍历,较慢
- 索引遍历,非常慢
- for-each遍历,较快
ArrayList适用于较多查询的(静态)数据,而LinkedList适用于频繁增删的数据。
Vector(同步):
- 和ArrayList类似,可变数组实现的列表
- Vector同步,适合在多线程下使用
- 原先不属于JCF框架,属于Java最早的数据结构,性能较差
- 从JDK1.2开始,Vector被重写,并纳入到JCF
- 官方建议在非同步情况下,优先采用ArrayList
Vector的便利操作(同上):
- Iterator遍历,较慢
- 索引遍历,慢
- for-each遍历,快
- Enumeration遍历,较慢
Vector基本和ArrayList功能相同,区别在于同步导致性能略差
第四节 集合Set
集合Set:
- 确定性:对任意对象都能判定其是否属于某一个集合
- 互异性:集合内每个元素都是不相同的,注意时内容互异
- 无序性:集合内的顺序无关
Java中的集合接口Set
- HashSet,基于散列函数的集合,无序,不支持同步
- TreeSet,基于树结构的集合,可排序的,不支持同步
- LinkedHashSet,基于散列函数和双向链表的集合,可排序的,不支持同步
HashSet:
- 基于HashMap实现的,可以容纳null元素,不支持同步
- add添加一个元素
- clear清除整个HashSet
- contains判定是否包含一个元素
- remove删除一个元素
- size大小
- retainAll计算两个集合交集
】
HashSet遍历:
- Iterator遍历,慢
- for-each遍历,快
- 遍历输出结果和input顺序不一致,无序
LInkedHashSet:
- 继承HashSet,也是基于HashMap实现的,可以容纳null元素
- 不支持同步
- 方法和HashSet基本一致
- 通过一个双向链表维护插入顺序
LinkedHashSet遍历:
- Iterator遍历,速度差不多
- for-each遍历,速度差不多
- 遍历输出结果与input顺序一致,是有序的
TreeSet:
- 基于TreeMap实现的,不可以容纳null元素,不支持同步
- add 添加一个元素
- clear 清除整个TreeSet
- contains 判定是否包含一个元素
- remove 删除一个元素
- size 大小
- 根据compareTO方法或指定Comparator排序
TreeSet遍历:
- Iterator遍历,速度差不多
- for-each遍历,速度差不多
- HashSet是无序输出的;LinkedHashSet是按照插入顺序进行遍历输出的;TreeSet是按照所存储对象大小升序输出的
HashSet, LinkedHashSet, TreeSet的元素都只能是对象。
HashSet和LInkedHashSet判定元素重复的原则:
- 判定两个元素的hashCode返回值是否相同,若不同,返回false
- 若两者hashCode相同,判定equals方法,若不通,返回false;否则返回true
- hashCode和equals方法是所有类都有的,因为object类有
TreeSet判定元素重复的原则:
- 需要元素继承自Comparable接口
- 比较两个元素的compareTo方法
"Cat类本身没有hashCode(),而是继承Object类的,而Object的hashCode()会返回对象信息和内存地址经过运算后的一个int值。两个不同的Cat(4)对象,他们的hashCode()返回值是不同的。"
"Dog类本身改写了hashCode()方法,其返回值是具体的size。所以两个不同Dog(4),他们的hashCode()返回值是相同的。"
"Tiger实现Comparable接口,所以必须实现compareTo方法来比较大小。但是HashSet的元素判定规则只和hashCode, equals这两个方法有关,和compareTo方法无关"
compareTo方法具体规则如下:
int a = obj1.compareTo(obj2);
if a > 0 -> obj1 > obj2
if a == 0 -> obj1 == obj2
if a < 0 -> obj1 < obj2
第五节 映射Map
Map映射:
- 数学定义:两个集合之间的元素对应关系
- 一个输入对应到一个输出
- {1, Alan}, {2, Jerry}, {Key, Value},键值对
Java中Map:
- Hashtable(同步,慢,数据量小)
- HashMap(不支持同步,快,数据量大)
- Properties(同步,文件形式,数据量小)
Hashtable:
- K-V对,K和V都不允许为null
- 同步,多线程安全
- 无序的
- 适合小数据量
- 主要方法:clear, contains/containsValue, containsKey, get, put, remove, size
Hashtable遍历:
- 根据Entry迭代器遍历:Iterator<Entry<Integer, String>> iter = ht1.entrySet().
- 根据Key迭代器遍历:Iterator<Integer> iter = ht1.keySet().iterator();
- 根据Key的Enumeration遍历:Enumeration<Integer> keys = ht1.keys();
- 三者速度相差不大
HashMap:
- K-V对,K和V都允许为null
- 不同步,线程不安全
- 无序的
- 主要方法: clear, containsValue, containsKey, get, put, remove, size
HashMap遍历:
- 根据Entry迭代器遍历,略快
- 根据Key迭代器遍历
LinkedHashMap:基于双向链表的维持插入顺序的HashMap
TreeMap:基于红黑树的Map,可以根据key的自然排序或者compareTo方法进行排序输出
Properties:
- 继承于Hashtable
- 可以将K-V对保存在文件中
- 适用于数据量少的配置文件
- 继承自Hashtable的方法:clear, contains/containsValue, containsKey, get, put, remove, size
- 从文件加载的load方法,写入到文件中的source方法
- 获取属性getProperty, 设置熟悉setProperty
第六节 工具类
JCF中的工具类:
- 不存储数据,而是在数据容器上,实现高效操作,例如排序和搜索
- Arrays类
- Collections类
Arrays:处理对象是数组
- 排序:对数组排序,sort/parallelSort
- 查找:从数组中查找一个元素,binarySearch
- 批量拷贝:从源数组批量复制元素到目标数组,copyOf
- 批量赋值:对数组进行批量赋值,fill
- 等价性比较:判定两个数组内容是否相同,equals
Collection:处理对象是Collection及其子类
- 排序:对List进行排序,sort
- 搜索:从List中搜索元素,binarySearch
- 批量赋值:对List批量赋值,fill
- 最大,最小:查找集合中最大/最小值,max,min
- 反序:将List反序排列,reverse
对象实现Comparable接口(需要修改对象类)
- compareTo方法:> 返回1,== 返回0,< 返回-1
- Arrays和Collections在进行对象sort时,自动调用该方法
新建Comparator(适用于对象类不可更改的情况)
- compare方法:> 返回1,==返回0,<返回-1
- Comparator比较器将作为参数提交给工具类的sort方法
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;
}
public int compareTo(person another){
int i = 0;
i = name.compareTo(another.name); //使用字符串比较
if(i == 0){
return age - another.age;
//如果名字一样,比较年龄,返回比较年龄结果
} else {
return i;
//如果名字不一样,返回比较名字的结果
}
}
}
Array.sort(ps);
————————————————————————————————————————————————————————————
public class Person2Comparator implements Comparator<Person2> {
public int compare(Person2 one, Person2 another){
int i = 0;
i = one.getName().compareTo(another.getName());
if(i == 0){
return one.getAge() - another.getAge();
//如果名字一样,比较年龄,返回比较年龄结果
} else {
return i;
//名字不一样,返回比较名字的结果
}
}
}
Arrays.sort(ps, new Person2Comparator());