day18_集合概述
Java的集合类主要由两个接口派生而出:Collection和Map。Collection和Map是Java结合框架的根接口,这两个接口又包含了一些子接口或实现类。
Collection的继承层次结构
Map的继承层次结构
由以上两图我们可以看出Java集合类有清晰的继承关系,有很多子接口和实现类。但是.
并不是所有子接口或实现类都是最常用的。
下面我们列举出最常用的几个子接口和实现类:
Collection-- > List 一> ArrayList 类
Collection-- > List 一> Linkeduist类
Collection-- > Set 一> HashSet 类
Collection–> Set一 > SortedSet接口-> TreeSet类
1.collection
常用方法
使用方法
public class Collection_01 {
public static void main(String[] args) {
//创建集合对象
ArrayList collection_01 = new ArrayList();
// 判断是否为空
System.out.println(collection_01.isEmpty());
// 集合中是不能保存基本类型的,需要转换为对应的包装类
// 这里会进行自动装箱为Integer类型,然后发生多态转型为Object类型,进行存储
collection_01.add(123);
collection_01.add(new Integer(1));
// 个数
System.out.println(collection_01.size());
System.out.println(collection_01.isEmpty());
// 删除,会调用要删除 元素的equals方法,但是Integer覆写了,所以可以把1删除
collection_01.remove(1);
A a =new A("张三");
A a1 = new A("张三");
collection_01.add(a);
// 使用集合保存自定义类型时,要注意是否覆写了equals方法,定义怎么算相等情况
collection_01.remove(a1);
// 把集合转换成数组
Object[] arr = collection_01.toArray();
for(Object object :arr){
System.out.println(object);
}
//清空集合
//collection_01.clear();
System.out.println(collection_01.size());
System.out.println("-----------------------");
Object[] arr1 = collection_01.toArray();
for(Object object :arr1){
System.out.println(object);
}
}
}
class A {
private String name;
public A(String name) {
super();
this.name = name;
}
}
注意contains 和remove
Contains(数据) : 判断集合中是否包含某个元素
Remove(数据 ) : 删除指定元素
两个方法底层都会自动调用该对象的equals方法
因为不管是判断是否包含还是删除,都要先找到这个数据,而找到只能比较
但是集合中保存的都是引用类型,所以比较只能使用equals方法
所以如果存储的是自定义类型,就要考虑equals方法的覆写问题
2.Iterator
- 在面向对象编程里,迭代器模式是一种设计模式,是一种最简单也最常见的设计模式。
- 它可以让用户透过特定的接口巡访容器中的每一个元素而不用了解底层的实现。
- 获取该集合的迭代器对象
- Iterator it = 集合对象.iterator();
三个方法 :
1 boolean hasNext() : 判断下面还有没有元素,如果有就返回true,没有就返回false
2 E next() : 获取下一个元素,并指向下一个元素
3 remove() : 删除当前指向的元素
- 三个方法的使用步骤 , 就是 1,2,3 按照这个顺序调用
- 注意 : 迭代器一旦创建,集合中就不能添加和删除元素(长度不能更改了)
如果添加或者删除了元素,那么迭代器必须重新生成
- 增强for循环 就是为了让用iterator循环访问的方式简单,写起来更方便,当然功能不太全,比如删除,还是要用iterator来删除
for 与 iterator 对比
Iterator的好处在于可以使用相同方式去遍历集合中元素,而不用考虑集合类的内部实现。
使用Iterator来遍历集合中元素,如果不再使用List转而使用Set来组织数据,则遍历元素的代码
不用做任何修改
使用for来遍历,那所有遍历此集合的算法都得做相应调整因为List有序,Set无序,结构不同,他们
的访问算法也不一样
for循环需要下标
常用方法
使用方式
public class Collection_02_Iterator {
public static void main(String[] args) {
//Collection c1 = new ArrayList();
//Collection c1= new HashSet();
Collection c1 = new LinkedList();
c1.add(1);
c1.add("abc");
// 判断是否包含
System.out.println(c1.contains(1));
// 1.创建迭代器
Iterator it = c1.iterator();
// 遍历判断下面是否有元素
while (it.hasNext()) {
// 获取并指向下一个元素
Object object = it.next();
System.out.println(object);
}
// 使用完之后想再次使用,需要重新创建
it = c1.iterator();
// 迭代器创建之后,不能添加和删除 , 必须重新生成迭代器
c1.add(2);
c1.add(3);
c1.remove(1);
// 需要重新创建迭代器
it = c1.iterator();
while (it.hasNext()) {
// 获取并指向下一个元素
Object obj = it.next();
System.out.println(obj);
// 使用迭代器的时候,不能更改集合个数,所以删除数据的时候不能使用集合的删除,应该使用迭代器的删除
// c1.remove(obj);
it.remove();
}
System.out.println(c1.size() + "----");
}
}
3.List
- List特点 : 有序 可重复
有序 : 添加顺序和取出顺序是一致的
- 可重复 : 就是可以有重复的数据
3.2 ArrayList
ArrayList : 底层是个Object数组 , 随机查询和更改效率高, 随机添加和删除 效率低
注: ArrayList底层是数组,下标从0开始
-
**默认初始化容量为10,扩大容量为原始容量的1.5倍**
-
**并且默认容量是第一次添加数据的时候设置的**
- 也就是说 我们 new ArrayList() 的时候,数组长度是为0的
-
**1.5倍 : 长度 + 长度>>1**
public class Collection_03_List_01 {
public static void main(String[] args) {
// 创建对象
// Vector 已经过时了,ArrayList是Vector的升级版,Vector是线程安全,而ArrayList是非线程安全的
List list = new ArrayList();
list.add(100);
list.add(123);
// [100, 123] 覆写了toString方法
System.out.println(list);
}
}
—————————————————————————————————
public class Collection_04_List_02 {
public static void main(String[] args) {
List list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
// add(E e ) : 尾部添加
// add(int index , E e ) : 添加到指定位置
// set(int index, E e ) : 更改指定位置上的元素值
// remove(Object object) : 根据元素内容删除
// remove(int index) : 根据索引删除
// get(int index) : 获取指定位置的数据
list.add(1, 4);
list.set(3, 33);
System.out.println(list.get(2));
// 这是根据索引删除
list.remove(1);
// 删除元素值为1
list.remove(new Integer(1));
System.out.println(list);
// 传统for遍历
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// foreach遍历
for (Object object : list) {
System.out.println(object);
}
// 迭代器遍历
Iterator it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
Collection提供排序方法:Collections.sort();
3.3 LinkedList
LinkedList : 底层是一个双向链表,随机查询更改效率低,随机添加和删除效率高
public class Collection_06_LinkedList_01 {
public static void main(String[] args) {
LinkedList list = new LinkedList();
// add(E e ) : 尾部添加
// add(int index , E e ) : 添加到指定位置
// set(int index, E e ) : 更改指定位置上的元素值
// remove(Object object) : 根据元素内容删除
// remove(int index) : 根据索引删除
// get(int index) : 获取指定位置的数据
// 首部添加
list.addFirst(1);
// 首部添加
list.push(11);
// 首部添加 成功返回true
list.offerFirst(111);
// 尾部添加
list.addLast(2);
// 尾部添加 成功返回true
list.offerLast(22);
// 尾部添加 成功返回true
list.offer(222);
// 上面这几个方法 没啥区别,本质就是 linkLast 和 linkFirst
list.add(1);
list.add(2);
list.add(3);
list.add(0, 4);
list.set(3, 33);
System.out.println(list.get(2));
// 这是根据索引删除
list.remove(1);
// 删除元素值为1
list.remove(new Integer(1));
System.out.println(list);
// 传统for遍历
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// foreach遍历
for (Object object : list) {
System.out.println(object);
}
// 迭代器遍历
Iterator it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
- 链表 : 保存的都是节点,一个节点有三个属性 , 添加的数据 , 上一个节点引用, 下一个节点引用
public class Collection_07_LinkedList_02 {
public static void main(String[] args) {
// size = 0 , f = null , l = null
LinkedList list = new LinkedList();
// size = 1 , f = a , l = a
list.add("a");
list.add("b");
list.add("c");
list.add("e");
list.add("f");
list.add("q");
System.out.println(list.get(2));
}
{
public static void main(String[] args) {
// size = 0 , f = null , l = null
LinkedList list = new LinkedList();
// size = 1 , f = a , l = a
list.add("a");
list.add("b");
list.add("c");
list.add("e");
list.add("f");
list.add("q");
System.out.println(list.get(2));
}
}