Collection、Map中的一些常用类和方法
Collection 接口
boolean add(E e) //添加元素 若确实改变的了集合就返回true,集合没有发生变化就返回false
boolean remove(Object o) //由于是共性方法,所以不能通过索引删除
boolean contains(Object o) //底层依赖equals进行判断是否存在
boolean isEmpty()
void clear()
int size()
Object[] toArray()
Iterator<E> iterator()
通用遍历方式:
- Iterator (可删除)
- 增强for
- forEach、lambda 表达式
Collections 工具类
注意: Collections 和Collection 不同
static void sort(list) 升序排序
static void reverse(list) 反转列表中的排列顺序
static void shuffle(list) 使用默认的随机源随机排列指定列表
Iterator 迭代器
迭代器 ,集合的专用迭代方式。
- 只能向下遍历,遍历完成之后指针不会复位
- 不依赖索引
- 当循环之后在次调用next()时,next()指向最后没有元素的位置会产生NoSuchElementException
Iterator<E> iterator() //返回此集合中元素的迭代器 依赖于集合而存在
boolean hasnext()
E next() //获取当前指向的元素 向下移动指针
void remove() //将会删除上一次调用next()方法时返回的元素,之前必须调用next()
default void forEachRemaining(element -> do something with element);//lambda表达式 将对迭代器每一个元素调用这个lambda表达式
List 接口
特点:有序、可重复、有索引。ArrayList、LinkList实现该接口
void add(index,element) add(e)
E remove(index) boolean remove(e)
E set(index,e)
E get(index)
ArrayList
特点:数据结构为数组 查询快 增删慢
底层原理:
- 利用空参创建的集合,在底层会创建一个名为elementData默认长度size为0的数组
- 添加第一个元素,底层会创建一个新的长度为10的数组
- 存满时,会扩容为原来的1.5倍
- 如果一次添加多个元素,1.5倍放不下,则新创建的数组长度以实际为准
LinkedList
特点:数据结构为链表 查询慢 增删快
//特有方法
addFirst(E e)
addLast(E e)
E removeFrist(E e)
E remoceLast(E e)
E getFirst()
E getLast()
ListIterator 列表迭代器
列表迭代器可以添加元素。允许程序按照任意方向遍历列表,ListIterator没有当前元素,他的光标位置始终位于调用previous()和调用next()所返回的元素之间,长度为n的列表的迭代器有n+1个可能的指针位置。
add(E) 在当前位置添加一个元素
set(E) 用新元素替换next或previous访问的上一个元素
boolean hasnext()
E next()
boolean hasprevious()
E previous()
int nextIndex() 返回下一次调用next方法时将返回的元素索引
Set 接口
特点:无序、不可重复、无索引
Set 接口等同于Collection接口,但Set的add方法不允许添加重复元素。Set存放的是对象的 引用, 没有重复 对象。HashSet、TreeSet实现该接口。
HasSet
特点:无序、不重复、无索引
采用哈希表(JDK8之前是数组+链表组成,JDK8之后数组+链表+红黑树)存储数据。哈希表增删改查性能都较好。
HashSet类按照哈希算法来存取集合中的对象,存取速度比较快。可以用add方法添加元素,contains方法已被重新定义。用来快速查找某个元素是否已经在集中,只查看一个 桶(bucket) 中的元素,而不必查看集合中所有的元素。没有带索引的方法,所以不能使用普通for循环遍历。中文有相同的哈希值,所以需要重写hashCode()方法和equal()方法
底层原理
- 创建一个默认长度为16,默认加载因为0.75的数组,数组名为table
- 调用元素的hashCode()方法得到哈希值,根据哈希值和数组长度计算出应存入的位置
- 若该位置是null则将该对象存入集合
- 若该位置有对象则调用equal()比较对象是否相等,若相等舍弃该对象。若不相等则将新元素直接挂在老元素下边,形成链表。(JDK8之前:新元素存入数组,老元素挂在新元素下边)
- 若数组元素个数为 数组长度 * 0.75(16*0.75) 则数组扩容为原来的两倍(16->32),当链表长度大于8而且数组长度大于等于64,则将当前链表转换为红黑树
注意:如果集合中存储的对象是自定义对象,则必须要重写hashCode和equals方法
LinkedHashSet
特点:
- 有序、不重复、无索引
- 底层基于哈希表,每个元素又多了一个双链表机制记录存储顺序,也就是说元素的存取和取出的顺序是一致的
TreeSet
特点:可排序、不重复、无索引
数据结构:红黑树
TreeSet实现了SortedSet接口,能够对集合中的对象进行排序,是一个 有序集合 ,这里的顺序不是指存取和取出的顺序,而是按照一定的规则进行排序,具体排序方式取决于构造方法 。
- TreeSet()自然排序
- TreeSet(Comparator comparator) 根据指定的比较器进行排序。
- 没有带索引的方法,所以不能使用普通for循环遍历
方法一:TreeSet无参构造,先在Student中实现Comparable接口,然后重写compareTo方法
@Override
public int compareTo(Student o) {
//return 0; //会将后边元素和前边比较为相等
//return 1; //1>0 正序
//return -1; //-1<0 倒序
int n = this.age - o.age; //this=s2 o=s1 //先按照主要条件(年龄)排序
int n2 = n == 0 ? this.name.compareTo(o.getName()) : n; //主要条件相同 按照次要条件(姓名)比较
System.out.println(this.getName() + "," + o.getName() + " this.age-o.age: " + n);
return n2;
}
方法二:TreeSet有参构造 传入Comparator对象,重写compare(T o1,T o2 )方法(定义的类型没有实现Compareable接口时使用)
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>(){
@Override
public int compare(Student o1, Student o2) {
int n = o1.getAge()-o2.getAge();
int n2 = n==0? o1.getName().compareTo(o2.getName()):n;
return n2;
}
});
综上所述
Map 接口
将键映射到值对象,不能包含重复键,当键重复的时候,后者会替换掉前者。 每个键最多可以映射到一个值,
V put(K k,V v) 添加元素
V remove(K k) 根据键删除键值对
void clear() 清空所有键值对
boolean containsKey(Object k) 判断集合是否包含指定键
boolean containsValue(Object v) 判断集合是否包含指定值
boolean isEmpty() 判断集合是否为空
int size() 返回键值对个数
HashMap
- 根据HashCode值存储数据,无序
- 访问速度快
- 最多允许一条键为null
- 不支持线程同步
Set<K> keySet() 返回包含所有key的Set集合
V get(key) 通过key获取value
Set<Map.Entry<K,V>> entrySet() 返回包含所有的键值对集合
Collection<V> values() 返回所有的value集合
TreeMap
能够把它保存的记录根据键(key)排序,默认是按升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。TreeMap不允许key的值为null。非同步的。