java中的容器(一):单例集合
List接口特点:有序、可重复。List接口中的常用方法在定义类中实现comparable接口中的comparTo类// 返回正数 :大 返回复数:小 返回0:相等 @Override public int compareTo(Users o) {//年龄小的比较大 return 1;} }
6:容器(一)
数组的length属性返回的是数组的长度,而不是元素的个数。
容器在内存中存储,不是磁盘。
6.1 容器的结构
左侧是单例集合,一次存储一个。
右侧是双例集合,一次存储两个元素<K,V>。
6.1.1 单例集合
List接口:存储有序、不可重复、动态数组。
Set接口:存储无序、不可重复、数学中的集合。
6.1.2 双例集合
6.2 单例集合的使用
6.2.1 Collection 中包含的抽象方法
6.2.2 List接口介绍
List接口特点:有序、可重复。
List接口中的常用方法
6.2.3 ArrayList容器类
ArrayList是List接口的实现类。
ArrayList底层是数组实现的。特点:查询效率高、增删效率低、线程不安全。
向ArrayList添加元素:
public class ArrayListTest {
public static void main(String[] args) {
//实例化ArrayList容器
List<String> list = new ArrayList<>();
//添加元素
list.add("houyiming");
//索引的数值不能大于元素的个数
list.add(2,"11");
}
}
从ArrayList获取元素:
用get方法
public class ArrayListTest {
public static void main(String[] args) {
//实例化ArrayList容器
List<String> list = new ArrayList<>();
//添加元素
list.add("houyiming");
//索引的数值不能大于元素的个数
list.add(1,"houerming");
list.add("housanming");
System.out.println(list.get(2)); // get()中的数不能越界
}
}
size()方法:返回列表的元素个数
删除元素
根据索引删除:
E remove(int index) //返回被删除元素
根据元素删除 :
boolen remove(Object o) //返回是否删除成功
替换元素
E set(int index,E element)
//返回被替换元素 将第index个元素替换为element
清空容器
void clear()
判断容器是否为空
boolean isEmpty()
判断容器中是否包含指定元素
boolean contains(object o)
查找元素的位置
int indexOf(object o) //查找第一次出现的位置
int lastIndexOf(object o) //查找最后一次出现的位置
将单例集合转换为数组
转换为Object数组
Object[] toArray()
list.toArray() // 数组的类型为Object
转换为泛型类型的数组
<T> T[] toArray(T[] a)
String[] strings =list.toArray(new String[list.size()]);
强制类型转换不能用于数组,将数组批量转换。
容器中的并接操作
boolean addAll(Collection<? extends E> c)
c 不能为空集
容器的交集操作
boolean retainAll(Collection<?> c)
容器的差集操作
boolean removeAll(Collection<?> c)
6.2.4 ArrayList源码分析
ArrayList底层用数组实现
ArrayList中的数组默认长度:
1.7版本为立即初始化,长度为10.
1.8版本为延迟加载,初始化的时候长度为0,用的时候再将长度改为10。 当10不够用的时候,以1.5倍(向下取整)扩容
6.2.5 Vector 容器类
Vector底层也是用数组实现的,在多线程时是线程安全的。
6.2.5.1 Vector源码分析
Vector中采用 立即初始化,长度为10.
Vector数组扩容以2倍扩容。
6.2.5.2 Stack容器
操作栈的方法
6.2.6 LinkedList 容器类
底层用双向链表实现链表实现
查询效率低,增加删除效率低,线程不安全
LinkedList的独有的方法
LinkedList源码分析
Node类:
链表中添加元素:
头尾添加元素:
尾部添加元素也是调用linkLast()
在指定位置添加元素:
public void add(int index, E element) {
checkPositionIndex(index);//检查index的值是否合法
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
Node<E> node(int index) { //查找到第index个节点
// assert isElementIndex(index);
if (index < (size >> 1)) { // 从头找
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else { // 从尾部开始找
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
void linkBefore(E e, Node<E> succ) { // 在上一步找到的节点前链接
// assert succ != null;
final Node<E> pred = succ.prev;
final Node<E> newNode = new Node<>(pred, e, succ);
succ.prev = newNode;
if (pred == null)
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}
获取指定位置元素:
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
private void checkElementIndex(int index) {
if (!isElementIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
删除指定位置元素:
public E remove(int index) {
checkElementIndex(index);
return unlink(node(index));
}
E unlink(Node<E> x) {
// assert x != null;
final E element = x.item;
final Node<E> next = x.next;
final Node<E> prev = x.prev;
if (prev == null) {
first = next;
} else {
prev.next = next;
x.prev = null;
}
if (next == null) {
last = prev;
} else {
next.prev = prev;
x.next = null;
}
x.item = null;
size--;
modCount++;
return element;
}
6.2.7 Set接口
Set特点:无序、不可重复。
Set中常用的实现类:HashSet、TreeSet
6.2.8 HashSet容器类
语序有Null元素,底层用HashMap实现,查询和增删效率都很高。
HashSet的使用
在Set容器中没有get(int index)方法,可以用for each循环。
HashSet存储特征
HashSet是一个不保证元素顺序且没有重复元素出现的的集合,是线程不安全的,允许有null元素。
HashSet底层使用HashMap存储数组,HashMap底层使用链表+数组的实现元素存储。由Hash值确定在数组中的位置,如果不同元素的Hash值相同,则使用拉链法存储。
在自定义对象中要重写hashcode和equals方法,才能实现元素不重复。
HashSet底层会对int(0到16)的数据默认进行排序(假排序)
产生假排序的原因:Integer的HashCode方法是直接返回其int值的,然后再模16,得到的结果大小排序于原数据相同。
HashSet的源码分析
HashSet的值存在于HashMap的Key中。
6.2.9 TreeSet容器类
自定义比较规则
在定义类中实现comparable接口中的comparTo类
// 返回正数 :大 返回复数:小 返回0:相等
@Override
public int compareTo(Users o) {
if (this.u8serAge < o.getU8serAge()){ //年龄小的比较大
return 1;
}
if (this.getU8serAge() == o.getU8serAge()){
return this.userName.compareTo(o.getUserName());
}
return -1;
}
}
通过比较器实现比较规则
public class StudentComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
if (o1.getAge() < o2.getAge()){
return 1;
}
if (o1.getAge() == o2.getAge()){
return o1.getName().compareTo(o2.getName());
}
return 1;
}
}
Set<Student> s = new TreeSet<>(new StudentComparator());
更多推荐
所有评论(0)