以下内容纯属个人理解,有错误请指出。
集合,是Java对数据结构成熟的实现,于JDK1.2之后正式引入。位于java.util包中,有两个接口Collection(存放单值),Map(存放键值对)
常用的数据结构
链表:由一组不必项链的内存结构,按特定顺序连接在一起的抽象数据类型
优点:空间是无限制的,且不需要连续的空间,插入和删除数据很快
缺点:存取慢(可以理解为向链表尾端存数据以及查询数据,因为都需要从头节点开始往后找)
二叉树:是树的一种,每个节点最多可具有两个子树
Java中用的二叉树基本为有序的二叉树,即根节点的左边都比其小,右边则大
查找数据的方式类似于二分查找
常用集合
数组:一开始学习java接触的集合,它是一种连续存储的线性结构,元素类型相同。
优点:存取速度快(根据下标可以快速的存取)
缺点:插入和删除元素很慢,空间通常有限制,需要大块连续的内存空间(删除或插入时都需要将数组里面的数据进行移动,空间是固定,扩容时原先的数组会留在内存中无法被gc回收,极大的降低了性能)
List接口:是Collection的子接口,它允许存放重复的数据
有两个常用实现类:ArrayList,LinkedList,前者线程是不安全的,其子类Vector是线程安全的,后者采用的双向链表的结构
Set接口,不允许存放重复的数据
常用实现类:
HashSet:散列存放(哈希表)
TreeSet:利用二叉树进行存放,采用的自然顺序(参考Ascii码),在存放自定义类型时,必须要让自定义的类实现Comparable接口,并实现CompareTo方法。
Map(全写为Mapping)接口:存放一个个的键值对,键不可重复
常用的方法
clear()//清空集合所有数据
keySet()//把所有的键做成一个单独的集合
put(K key, V value)//存放一对键值
remove(Object key)//删除该键值对,并返回值
remove(Object key, Object value)//当传入的键值对相互对应时进行删除返回的是布尔值
删除成功是true反之false
get(Object key)//通过传入的键获取到对应的值
size()//获取当前存放的键值对的个数
常用实现类
HashMap,线程不安全,效率高
HashTable,线程安全,效率低,不保证存放的顺序
ConcurrenHashMap,采用分段锁机制保证线程安全,效率比较高
TreeMap,自动排序(从小到大)
LinkedHashMap,可以保证存储时的顺序
ps:影响HashMap性能有两个因素,一是初始容量、二是散列因子(默认为75%)。初始容量太小会导致频繁扩容,散列因子小时内存使用率不高,过大时不便于查找数据
当自定义的对象作为哈希值的键存储时,不要随意更改对象的值。因为Map存放数据时靠对象的值所计算的哈希值存放的,对象的值进行了更改大概率会导致找不到键值对
迭代器,用于遍历集合,
Iterator,主要用来迭代Collection的子类集合
ListIterator,用于便利List子类集合
forEach:Java中用于迭代数组或集合,会默认使用最优的算法操作
使用格式
Iterator
//首先创建一个集合对象
LinkedList<String> ll = new LinkedList<String>();
ll.add("haha");
ll.add("hihi");
ll.add("hi");
ll.add("hello");
ll.add("heihei");
//添加完数据后,创建Iterator对象
Iterator<String> iterator = ll.iterator();
while (iterator.hasNext()){
System.out.print(iterator.next()+" ");
}
//ListIterator操作与Iterator差不多
ListIterator<String> iter = ll.listIterator();
while (iter.hasNext()){
System.out.print(iter.next()+" ");
}
//forEach:
for (String s:ll) {
System.out.print(s+" ");
}
比较器
内部比较器Comparable,在定义类时实现该接口,与compareTo方法即可
外部比较器Comparator,在排序时新建Comparator。
compareTo方法:this与串入的o比较,返回正整数表示this大,0相等,负数小
//Comparable:
public class Student implements Comparable<Student>{
private String name;
private int age;
private double result;
/**
* 对成绩进行降序排序
* 若成绩一样则对年龄做升序
* @param o
* @return
*/
@Override
public int compareTo(Student o) {
if (result > o.result){
return -1;
}
if (result < o.result){
return 1;
}
if (age > o.age){
return 1;
}
if (age < o.age){
return -1;
}
return 0;
}
}
//Comparator:
Arrays.sort(s, new Comparator<Student2>() {
/**
* 对成绩进行降序排序
* 若成绩一样则对年龄做升序排序
* @param o1
* @param o2
* @return
*/
@Override
public int compare(Student2 o1, Student2 o2) {
if (o1.getResult() > o2.getResult()){
return -1;
}
if (o1.getResult() < o2.getResult()){
return 1;
}
if (o1.getAge() > o2.getAge()){
return 1;
}
if (o1.getAge() < o2.getAge()){
return -1;
}
return 0;
}