数据结构小节(1)

接口总结

UML类图中的关系

  1. 依赖 : 局部变量和外部类的关系
  2. 关联 : 简单理解的话就是成员变量
  3. 聚合:has-a的成员变量,整体与部分分离,有各自独立的生命周期。eg: 公司&员工,电脑&cpu
  4. 合成: contains-a关系的成员变量,外部类和内部成员保持同一个生命周期
  5. 实现 : 实现类 实现→ 接口 比如Chinese实现Person
  6. 泛化 : 父类与子类的关系,继承为其中一种

集合的分类

  • 集合主要被分为Collection和Map两个接口
  • Collection被List和Set继承
  • List被AbstractList实现,然后分为ArrayList,LinkedList和Vector
  • Set被AbstractSet实现,然后分为HashSet,TreeSet
  • Map衍生出HashMap,HashTable和TreeMap

Collection接口

Collection接口基本操作

  1. add()
  2. addAll()
  3. clear();
  4. contains();
  5. ...
  6. ...

AbstractCollection实现方法

  1. contains()
  2. isEmpty()
  3. toArray()
  4. remove()
  5. clear()

子接口List

一个list是元素有序,可以重复,可以为null的集合
最好做法是: 默认使用ArrayList,多插入删除时使用LinkedList,Vector太慢避免使用

List实现有序,可重复的原理

  1. List的数据结构就是一个序列,存储内容时直接在内存中开辟一块连续空间,然后将空间地址与索引对应
  2. ArrayList本质为数组
  3. List元素存储是互不干扰,所以可以重复(与Set有很大区别)

List接口定义的方法

除了Collection自带方法还提供以下的操作:

  • 位置相关:比如get,set,add,addAll,remove;
  • 搜索: 从list中查找元素位置, indexof,lastindexof
  • 迭代: 使用Iterator的扩展版迭代器,ListIterator进行迭代操作
  • 范围性操作: subList;

集合操作

public boolean equals(Object o){
​    retrun this == o;
}
  • 比较地址是否相等,如果要比较内容,需要重写.equals().
    remove(), contains(), indexof() 都需要用.equals();
public boolean contains(Object object){
​    Object[] a = array;
​    int s = size;
​    if (object!= null){
​    for (int i =0;i < s; i++){
​        if(object.equals(a[i])){
​            return true;
​        }
​    }
}
}
  • indexof() 方法差不多,但是要多一个else{} 遍历Object等于null的情况

位置访问,搜索

get,set,add,remove

  • set,remove方法返回被覆盖,被删除的元素

indexOf,lastIndexOf

  • 返回指定元素在list中的首次出现,最后一次出现位置(lastIndexOf为倒序遍历)

addAll(int,Collection)

  • 在指定地点插入集合所有元素,元素按照迭代器Iterator返回的先后顺序进行插入

简单List swap()

public static <E> void swap(List<E> a, int i, int j){
​    E temp = a.get(i);
​    a.set(i,a.get(j));
​    a.set(j,temp);
}

局部范围操作

  • subList本质为返回原来list的引用,改变了开始位置的offset和size.
  • return new SubAbstractListRandomAccess<E>(this, start, end);
  • 对subList改动同样会影响原来的list;

List于Array的区别

相似之处

  • 都可以表示一组相同类型的对象
  • 都是用下标进行索引

不同之处

  • 数组可以存任何类型元素
  • List不可以存基本数据类型,必须包装
  • 数组容量固定, List容量可动态正常
  • 数组效率高, List由于需要维护,效率相对低

总结

  • 容量固定时先使用数组, 容纳类型更多更高效
  • 容量不确定的情况下, List更有优势

List与Array间的转换

  • Object[] toArray(): 返回一个包含List中所有元素的数组
  • T[] toArray(T[] array): 作用同上,不同的是,array长度大于List元素是.
    会使用参数array保存List中的元素; 否则会创建一个新的array存放List中元素

迭代器

  • List继承了Collection的iterator()方法,可以获取Iterator,使用它进行向后遍历
  • 在此基础上, List还可以获取更强大的迭代器ListIterator
  • ListIterator可以对list进行向前,向后双向遍历,同时还允许进行set,add,remove等操作

例子

public int indexOf(E e) { for (ListIterator<E> it = listIterator(); it.hasNext(); ) if (e == null ? it.next() == null : e.equals(it.next())) return it.previousIndex(); // Element not found return -1; }
public static <E> void replace(List<E> list, E val. E newVal){
​    for(ListIterator<E> it = list.listIterator();it.hasNext();){
​       if (val == null ? it.next == null ; val.equals(it.next()));
​       it.set(newVal);
​       }
}
posted @ 2018-10-23 22:40  kojimako  阅读(107)  评论(0编辑  收藏  举报