javase笔记6----集合1
集合的定义
集合Collection,也是一个数据容器,类似于数组,但是和数组是不一样的。集合是一个可变的容器,可以随时向集合中添加元素,也可以随时从集合中删除元素。另外,集合还提供了若干个用来操作集合中数据的方法。集合里的数据,称之为元素(elements);
注意:
集合只能用来存储引用类型的数据,不能存储八大基本数据类型的数据。
集合与数组
1. 数组是定长的容器,一旦实例化完成,长度不能改变。集合是变长的,可以随时的进行增删操作。
2. 数组中可以存储基本数据类型和引用数据类型的元素,集合中只能存储引用数据类型的元素。
3. 数组的操作比较单一,只能通过下标进行访问。集合中提供了若干个方便对元素进行操作的方法。4. 在存储引用类型时,集合与数组,存储的其实都是对象的地址。
Collection接口
简介
Collection 接口是 List、Set 和 Queue 接口的父接口,该接口里定义了他们三个子接口的共同方法。既可用于操作 Set 集合,也可用于操作 List 和 Queue 集合。作为父接口,其子类集合的对象,存储元素的特点,可能是无序的,也可能是有序的,因此在父接口中并没有定义通过下标获取元素的方法功能。
常用方法
public static void main(String[] args){
Collection<String> c = new ArrayList<>();
//1. E add(E e) 向集合中添加元素
c.add("A");
c.add("B");
//2. boolean isEmpty() 判断一个集合中是否为空
boolean b = c.isEmpty();
System.out.println(b);
//3. int size(): 返回的是集合元素的个数
System.out.println(c.size());
//4.删除从前往后第一个匹配到的元素
c.remove("B");
}
public static void main(String[] args){
Collection<String> c2 = new ArrayList<>();
c2.add("zhangsan");
c2.add("lisi");
c2.add("wangwu");
//5.addAll(Collection c) 向集合中批量的添加元素(将另一个集合中的元素依次添加到这个集合中)
c1.addAll(c2);
System.out.println(c1);
//6.contains(Object o) 查看集合中是否包含指定元素
boolean b = c2.contains("zhangsan");
System.out.println(b);
//7.boolean containsAll(Collection c) 判断参数集合中的每一个元素是否都在当前集合中包含
boolean b1 = c1.containsAll(c2);
System.out.println(b1);
}
public static void main(String[] args){
Collection<String> c3 = new ArrayList<>();
c3.add("A");
c3.add("B");
c3.add("C");
c3.add("B");
c3.add("D");
c3.add("D");
//8.boolean equals(Object o)判断两个集合是否相同,两个集合中的元素数量、元素一一对应
System.out.println(c1.equals(c3));
//9.boolean removeAll(Collection<?> c)从集合中删除另一个中所具有的交集元素
c3.removeAll(c);
//10.boolean retainAll(Collection c) 保留在另外一个集合中存在的元素
Collection<String> c5 = new ArrayList<>();
c5.add("A");
c5.add("B");
c3.retainAll(c5);
System.out.println(c3);
//11.void clear() 清空集合
c3.clear();
System.out.println(c3);
}
集合的迭代
1. 集合的迭代,就是指集合的遍历操作
2. 几乎所有的集合子类型都实现了迭代接口Iterable
3.迭代接口提供了多个方法,用于迭代
- boolean hasNext(): 用于判断集合中是否有下一个元素。
可以形象的认为有指针,指针的最初位置在第一个元素的前面。
- E next(): 用于返回指针指向的那个元素,
然后指针向后移动,为下一次的判断做准备
- E remove(): 用于删除指针所指向的那个元素。
注意:在使用迭代器时,不可以调用集合自己的remove方法。
第一种方法:增强for循环
语法:
for(String ele : collection){
System.out.println(ele);
}
注意:
1.增强for循环中不允许对集合中的元素进行修改,修改是无效的
2.增强for循环中不允许对集合的长度进行修改,否则会出现 ConcurrentModificationException
public static void main(String[] args){
Collection<Integer> c = new ArrayList<>();
c.add(1);
c.add(2);
c.add(3);
for(Integer i : c){
System.out.println(i+ " ");
}
第二种方法:使用迭代器
迭代器Iterator,是一个接口, Collection集合中有一个方法 iterator() 可以获取这个接口的实现类对象。在这个迭代器中,维护了一个引用,指向集合中的某一个元素。默认指向一个集合前不存在的元素,可以认为是下标为-1的元素。
迭代器的工作原理:循环调用 next() 方法进行向后的元素指向,并返回新的指向的元素。同时,在向后进行遍历的过程中,使用 hasNext() 判断是否还有下一个元素可以迭代。
注意:
1.不应该对集合中的元素进行修改
2.不应该对集合的长度进行修改
3.如果非要修改,需要使用迭代器的方法,不能使用集合的方法。
//第一步:获取要遍历的集合对象的迭代器对象
Iterator<Integer> it = c.iterator();
//第二部:看是否有下一个元素
while(it.hasNext()){
//第三步:拿到元素
Integer a = it.next();
System.out.println("a:"+a);
List接口
简介
List 是一个元素有序、且可重复的集合,集合中的每个元素都有其对应的顺序索引,从0开始.List 集合里添加了一些根据索引来操作集合元素的方法.
ArrayList和LinkedList
这两个类都是List接口的实现类(子类)。
- ArrayList是实现了基于动态数组的数据结构,对象存储在连续的位置上
- LinkedList基于双链表的数据结构,链表中的每个节点都包含了前一个和后一个节点的引用。
- 对于随机访问get和set,ArrayList绝对优于LinkedList,因为LinkedList要移动指针。
- 对于插入和删除操作add和remove,LinkedList比较占优势,因为ArrayList要移动数据。
常用方法
1. 添加元素
boolean add(E e) 向列表末尾添加指定的元素
void add(int index, E element) 在列表的指定位置添加元素
boolean addAll(Collection c ) 将集合c中的所有元素添加到列表的结尾
boolean addAll(int index, Collection c) 将集合c中的所有元素添加到列表的指定位置
2. 获取元素
E get(int index) 返回列表指定位置的元素
List<String> names = new ArrayList<>();
List<Integer> ages= new ArrayList<>();
//向列表末尾添加指定的元素
names.add("lily");
//在列表的指定位置添加元素
names.add(1,"zeven");
ages.add(18);
ages.add(20);
//将集合ages中的所有元素添加到列表的结尾
names.addAll(ages);
//将集合ages中的所有元素添加到列表的指定位置
names.addAll(1,ages);
//获取指定索引处的元素
System.out.println(names.get(1));
3. 查找元素
int indexOf(Object obj) 返回列表中指定元素第一次出现的位置,如果没有该元素,返回-1
int lastIndexOf(Object obj)
返回列表中指定元素最后一次出现的位置,如果没有该元素,返回-1
4. 移除元素
E remove(int index) 移除集合中指定位置的元素,返回被移除掉的元素对象
5. 修改元素
E set(int index, E element)
6.截取子集
List subList(int fromIndex, int toIndex)
截取子集,返回集合中指定的fromIndex 到 toIndex之间部分视图,包前不包后
//查找元素
int a = names.indexOf("lily");
int b = names.lastIndexOf("zeven");
//移除元素
boolean b = names.remove("lucy"); //false
//修改元素
String names1 = names.set(2,"mike");
//截取子集
List names2 = names.subList(2,4);
Queue子接口
简介
- 队列Queue也是Collection的一个子接口,它也是常用的数据结构,可以将队列看成特殊的线性表,队列限制对线性表的访问方式:只能从一端添加(offer)元素,从另一端取出(poll)元素。
- 队列遵循先进先出(FIFO first Input First Output)的原则
- 实现类LinkedList也实现了该接口,选择此类实现Queue的原因在于Queue经常要进行添加和删除操作,而LinkedList在这方面效率比较高。
主要方法:
- boolean offer(E e): 从队列的尾部进入
- E poll(): 从队列的头部出来
- E peek(): 查看头部的元素
Deque
Deque是Queue的子接口,定义了所谓的”双端队列”,即从队列的两端分别可以入队(offer)和出队(poll)。同样,LinkedList实现了该接口
如果将Deque限制为只能一端入队和出队,则可以实现“栈”(Stack)的数据结构,对于栈而言,入栈被称为push,出栈被称为pop。遵循先进后(FILO)出原则