集合类体系结构图
注意(本文中提到的有序不是排序,而是指元素输出来的顺序和我们输入时的顺序保持一致)
Collection
- 集合只能存储引用类型
- Collection是集合的顶层接口,List和Set是它的两个子接口
- ArrayList,Vector,LinkedList是List接口的三个实现类,HashSet,TreeSet是Set接口的两个实现类
ArrayList,Vector,LinkedList三者的区别:
- ArrayList和Vector数组实现的,所以可以根据索引直接查找到指定的集合元素,二者查找速度快,而增加和删除都需要数组移动,所以增加,删除慢,ArrayList是线程不安全的,Vector是线程安全的,效率比ArrayList低。
- LinkedList底层是链表实现的,所以它添加和删除操作比较快,查找慢。
Collection接口中的常用方法
- boolean add();添加集合元素
- boolean addAll();添加一个集合元素
- void clear();清除所有元素
- boolean remove;(Object o);移出一个指定元素
- boolean contains;(Object o);是否包含某个元素
- boolean containsAll;(Collection c);是否包含某个集合中所有的元素
- boolean isEmpty();判断集合是否为空
- int size();返回集合的长度,即集合中元素的个数
- Iterator i terator();迭代方式获取元素
- boolean retainAll(Collection c);返回两个集合的交集
- Object [ ] toArray();将集合转换成数组
迭代器遍历集合元素的使用
迭代器是专门用来进行集合元素的遍历的
//代码如下:
public class IteratorDemo {
public static void main(String [] args) {
Collection<String> c=new ArrayList<String>();
c.add("hello");
c.add("my");
c.add("good");
c.add("friends");
Iterator<String> it=c.iterator();
while(it.hasNext()) {
System.out.print(it.next()+" ");
}
}
}
- 思考:迭代器Iterator为什么不定义成一个类,而是一个接口?
因为各集合类的数据结构和存储方式有所差异,所以遍历的方式也不同。所以只提供遍历的接口,将这些具体实现交给不同的集合,让它们实现适合自己的遍历方式。
List接口
- List集合可有重复元素
- List集合有序,此有序指元素在集合中的存储顺序和输入元素的顺序一致
- ArrayList特有方法:(指相对于父类或者接口新增加的方法)
void add(int i,Object o);在指定位置i插入元素o
Object get(int i);获取指定位置的元素。
ListIterator listIterator ();List专用迭代器
ListIterator listIterator (int i);从指定位置开始迭代
boolean remove(int i);移除指定元素
Object set(int i, E e);用元素e替换指定位置的元素
List sub(int s,int e);截取s和e之间的元素,不包括s和e位置 (从AbstractList 类中继承来的方法) - Linked List特有方法
addFirst();开头添加结点
addLast();尾部添加结点
getFirst();得到头部结点元素
getLast();得到尾部结点元素
removeFist();移除并返回头部结点
removeFirst();移除并返回尾部结点
set接口
- set集合里面的元素不可重复
- 无序,元素存储的顺序和元素输入的顺序不同
- HashSet(不保证迭代顺序,也不保证该顺序恒久不变)
- 关于HashSet保证元素的不可重复:
它的add()方法里默认调用了HashMap的put()方法来添加元素
该方法在添加元素之前,通过hashCode()方法和equals()方法来判断添加的两个元素是否相同,相同就不添加。从而保证了元素的唯一性。 - LinkedHashSet(底层使用哈希表和双向链表)哈希使得此集合元素不可重复,双向链表保证了它的有序(此处的有序是指存储元素的顺序和我们输入元素的顺序一致)
- TreeSet底层使用红黑树(自平衡二叉树)实现,元素是有排序的(使用元素的自然顺序(默认)或者根据set提供的comparator来进行排序,具体使用哪种排序规则,取决于所用的构造方法)
关于Treeset集合如何实现不可重复和自然排序简单解析(利用红黑树实现):
eg:以下序列:20 18 23 22 17 24 19 18 24
规则:
1.第一个元素存进来时,直接作为根节点
2.从第二个元素开始,每个元素从根节点开始比较:大,做右孩子。小,做左孩子。相等,不存储。
所以上面序列存储完成后如下图:
之后再中序遍历(左根右)就得到一个排好序的序列。(17,18,19,20,22,23,24)
这样就可以通过利用红黑树,保证了TreeSet的元素唯一性和自然排序
Map
Map
- 以K-V(键值对)的形式存储元素
- 常用方法:
clear();移除所有元素
containsKey(object key);集合中是否包含此键
containsValue(Object value)集合中是否包含该值
entrySet();返回一个k-v对象集合
get(Object key);根据键得到值
keySet();返回集合中所有键的集合
Values();返回集合中所有值的集合
put(k k,V v);添加键值对
remove(Object key);根据键删除对应的值
size();得到集合的大小 - 关于put(K k,V v)方法的注意点:
put方法,当key是第一次存储,方法返回值是null,当key不是第一次存储,方法返回值是上一次的value,并用此时新的value覆盖以前的值。代码执行效果如下: - 遍历Map的两种方法:
Map<Integer,String> map=new HashMap<Integer,String>();
map.put(1,"一");
map.put(2,"二");
map.put(3,"三");
map.put(4,"四");
map.put(5,"五");
//方式一:使用keySet()方法得到键的集合,根据键来得到对应的值
Set<Integer> set=map.keySet();
for(Integer key:set) {
String value=map.get(key);
System.out.println(key+"---"+value);
}
System.out.println("------------------------------------------");
//方式二:使用entrySet()方法得到键值对对象的集合。再根据键值对对象来获取元素
Set <Map.Entry<Integer,String>> setEntry=map.entrySet();
for(Map.Entry<Integer,String> entry:setEntry) {
Integer k=entry.getKey();
String v=entry.getValue();
System.out.println(k+"---"+v);
}
执行结果如下:
(个人学习总结,仅供参考,错误之处请指正,谢谢)