一、集合框架:
1、数组和集合操作的都是内存,要区别我们的数据持久化。集合也称作容器。
2、Collection是一个接口,内有子接口List、Set、Queue
(1)接口List,实现的类有ArrayList(是List的主要实现类)、LinkedList、Vector。
特点:List是有序的、可重复的
(2)接口Set,特点:无序不可重复
(3)Map(以后再说)
3、java5 之前没有泛型,因为存储的时Object,所以集合会丢失数据类型。泛型可以记住结合中的对象的数据类型。
二、集合和数组之间的区别:
1、数组存储数据时,一旦初始化,长度就固定了。并且只能存储单一的数据类型。
2、集合:可以存储多个对象,而且是可变长的。
三、数组存储数据的缺点:
1、一旦初始化。长度就确定了
2、只能存单一的数据类型
3、效率比较低(增删改总会涉及大量的元素移动)
四、集合和数组的使用:
1、能用集合也能用数组的时候,统一使用集合。
2、对返回值有明确要求时,使用数组。
五、集合的实现及方法------ArrayList:
1、Collection coll = new ArrayList(); //接口的引用可以指向一个实例(多态)
2、add() 向集合中添加一个元素(对象,可以添加一个数组)
coll.add(要添加的元素);
3、addAll() 将指定集合中的所有元素添加到当前集合中。
coll.addAll(要添加的集合);
4、clear() 从该集合中溢出所有元素
coll.clear();
5、contain() 判断当前集合中是否包含指定对象,如果包含返回True,否则返回False。
其比较的是内容,是通过调用cntain()括号中对象的equals方法进行比较(因为自动装箱的时候,会重写里面的比较方法,重写为equals),只要找到相同的元素就不再执行了。
coll.contain(要查找的元素);
6、containAll() 判断当前集合是否包含指定集合中的所有元素,如果包含返回True,否则返回False。
其也是通过对象中的equals方法进行比较
coll.containAll(要判断的集合);
7、equals() 判断两个集合是否相等
coll.equals(一个集合类)
8、hashCode() 找到集合的位置(哈希值)
9、isEmpty() 判断集合是否为空
10、iterator() 迭代器,返回当前集合中的迭代器
是设计模式中的一种,主要是用来遍历Collection集合,且本身不具备承载对象的能力,必须有一个被迭代的集合。
java.util.Iterator iterator = coll.iterator ();
System.out.println(Iterator.next());
System.out.println(Iterator.next());
System.out.println(Iterator.next()); //游标移到最后以为
直到遍历完集合中所有元素,若继续遍历则需要抛出异常。
基于一次只能取一个元素,所以我们使用while()方法进行循环。
while(Iterator.hasNext()) //Iterator.hasNext是判断集合中是否有下一个元素(游标默认指向第一个元素之上,相当于指向一个空的数值)
{
System.out.println(Iterator.next()); //将游标向下指一个元素,并返回所指向的元素
}
同一个集合中的迭代器每次创建一个都是全新的,互不影响。即每一次使用coll.iterator都会创建一个新的迭代器
11、remove() 移除集合中指定的对象
12、removeAll() 移除当前集合中与指定集合相同的所有元素(相当于做集合当前集合减去一个特定集合)
13、retainAll() 保留一个集合中与指定集合中相同的元素(求交集)
14、size() 返回当前集合中的元素个数
15、toArray() 以正确的顺序返回一个具有当前集合元素的数组
Object[] objects = coll.toArray;
六、foreach循环的写法:
1、for (String i:m){ //m是之前定义的一个String类型的数组,实质也是通过迭代器实现,如果在循环内操作,不会改变m中的值
若m是个对象,则在循环内操作,会改变m中的值。类似于引用传递和值传递。
System.out.println();
}
2、for循环底层实质是一个迭代器
七、List
1、特点:有序、可重复
2、三个实现类的不同点:
(1)ArrayList(也叫动态数组) 底层以数组的方式实现,效率比较高,是线程不安全的。如有频繁查询,则使用ArrayList(通过数组的索引查询会很高效)。
a、Object[] elementData 底层实现的,并未指定长度。
b、add() 通过扩容elementData实现的(可以通过两个字符串拼接进行扩容)
c、设计开法推荐使用有参构造,这样可以避免扩容:
ArrayList arr = new ArrayList(50);//长度未50
(2)LinkedList:底层为双向链表的数据结构,所以其进行频繁的插入及删除时效率较高。
a、linkeList lk = new LinkedList();
(3)Vector:也是数组,但其为线程安全。
3、List的常用方法:
(1)add(int index,E element);添加一个元素到指定位置,return void;
(2)add(Collection<?> c);添加一个集合到指定位置,return boolean;
(3)get(int index);得到指定位置的一个元素,return Object;
(4)LastIndexOf(Object o);返回一个指定元素最后一次出现的索引,若不存咋此元素,则返回-1,return int;
(5)remove(Object o);移除第集合中一次出现的指定元素,return Object;
(6)set(int index,E element);返回指定位置的元素
(7)subList(int fromIndex,int toIndex);返回一个集合中指定区间的集合(左闭右开)。
4、如何迭代ArrayList
(1)通过使用迭代器(继承于Collection)
(2)通过hasPrevious、Previous
(3)通过foreach循环
八、Set
1、Set集合的存储特点:
(1)无序、不可重复的。
(2)底层是通过数组+链表的形式存储的。
(3)添加元素的时候会携带元素对象本身的一个hash值,通过这个hash值计算得出元素的村粗位置。
继续添加元素是,要判断元素是否相等时,所以需要覆写hashCode和equals方法:先判断哈希值是否相等,若不想等,则集合中不存在该元素;若相等,则进行equals比较,若相等,则说明是相同元素,不存储;若不相等,则创建一个链表,将链表指向集合中已有hash值元素,将该元素存在链表里面(7上8下,jdk1.7之前链表往上走,jdk1.8之后链表往下走)。
注意:在Set中式通过Hash值和equals同时进行判断的。
(4)Set中的方法都来源于Collection类;
2、主要实现类:HashSet(主要实现类)、LinkedSet、TreeSet
(1)HashSet:是线程不安全的,可以为null。
(2)LinkedHashSet:是HashSet的子类,可以按照集合存储的顺序来遍历。
a、同样是通过哈希值来决定元素存储位置,使用双向链表保存数组的次序(及元素数组中放着双向链表节点,数组位置是hash值,双向链表存在其结点对应的hash值,用于记录输入顺序)。其并不是真正有序。
b、查找效率比较高。插入效率较HashSet稍微高那么一点点。
(3)TreeSet:存储的是树形结构,可以按照集合元素的对象的属性进行排序(底层是按照二叉树中的红黑树结构来存储的),其中的类型必须是一致的。
a、是sortedSet接口的一个实现类,可以使集合元素处在排序状态(自然排序),其添加时只能添加同一个类的实例。当需要将对象放入TreeSet中,重写该equals时,要保证其和compareTo保持一致。
3、有序和无序:
(1)有序:如数组添加元素,是获得其索引再进行添加
(2)无序:不等于随机性,是通过找到集合对应元素对象的哈希值,然后通过某种计算得到的存储位值。不是通过底层数组索引来存储的。
4、自然排序和定制排序
(1)自然排序:是TreeSet默认采用的排序方式,调用集合元素类的compareTo方法比较元素的大小,然后将集合升序排列。
ComparaTo(T o):若return -1 表示放在红黑树的左边,逆序输出这个数。若return 0 表示元素相等,输出第一个这个数;若return 1 表示放在红黑树的右边,顺序输出这个数。
。