一、集合
1、什么是集合
存储对象的容器,面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,存储对象,集合是存储对象最常用的一种方式。
集合的出现就是为了持有对象。集合中可以存储任意类型的对象, 而且长度可变。在程序中有可能无法预先知道需要多少个对象, 那么用数组来装对象的话, 长度不好定义, 而集合解决了这样的问题。
2、集合和数组的区别
数组和集合类都是容器,数组长度是固定的,集合长度是可变的。数组中可以存储基本数据类型,集合只能存储对象数组中存储数据类型是单一的,集合中可以存储任意类型的对象。
①、集合类的特点
用于存储对象,长度是可变的,可以存储不同类型的对象。
②、数组的缺点
存储类型单一的数据容器,操作复杂(数组一旦声明好不可变)
3、集合的分类
---|Collection: 单列集合
---|Collection: 单列集合
---|List: 有存储顺序, 可重复
---|ArrayList: 数组实现, 查找快, 增删慢
由于是数组实现, 在增和删的时候会牵扯到数组增容,
以及拷贝元素. 所以慢。数组是可以直接按索引查找, 所以查找时较快
---|LinkedList: 链表实现, 增删快, 查找慢
由于链表实现, 增加时只要让前一个元素记住自
己就可以, 删除时让前一个元素记住后一个元素, 后一个元素记住前一个元素.
这样的增删效率较高但查询时需要一个一个的遍历, 所以效率较低
---|Vector: 和ArrayList原理相同, 但线程安全, 效率略低
和ArrayList实现方式相同, 但考虑了线程安全问题, 所以效率略低
---|Set: 无存储顺序, 不可重复
---|HashSet
---|TreeSet
---|LinkedHashSet
---| Map: 键值对
---|HashMap
---|TreeMap
---|HashTable
---|LinkedHashMap
二、集合类(Collection)
Collection接口有两个子接口:
List(链表|线性表)
Set(集)
java.util.Collection
---| Collection 描述所有接口的共性
----| List接口 可以有重复元素的集合
----| Set 接口 不可以有重复元素的集合
2.1. Collection接口的共性方法
增加:
1:add() 将指定对象存储到容器中
add 方法的参数类型是Object 便于接收任意对象
2:addAll() 将指定集合中的元素添加到调用该方法和集合中
删除:
3:remove() 将指定的对象从集合中删除
4:removeAll() 将指定集合中的元素删除
修改
5:clear() 清空集合中的所有元素
判断
6:isEmpty() 判断集合是否为空
7:contains() 判断集合何中是否包含指定对象
8:containsAll() 判断集合中是否包含指定集合
使用equals()判断两个对象是否相等
获取: 9:int size() 返回集合容器的大小
转成数组10: toArray() 集合转换数组
练习:集合中添加自定义对象
class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int hashCode() {
return this.name.hashCode() + age;
}
@Override
public boolean equals(Object obj) {
Person p = (Person) obj;
return this.name.equals(p.name) && this.age == p.age;
}
@Override
public String toString() {
return "Person :name=" + name + ", age=" + age;
}
}
public static void main(String[] args) {
Person p1 = new Person("张三", 19);
Person p2 = new Person("李四", 20);
Person p3 = new Person("王五", 18);
Collection list = new ArrayList();
list.add(p1);
list.add(p2);
list.add(p3);
// isEmpty() 判断集合是否为空
boolean empty = list.isEmpty();
System.out.println(empty);
// 返回集合容器的大小
int size = list.size();
System.out.println(size);
// contains()判断集合何中是否包含指定对象
boolean contains = list.contains(p1);
System.out.println(contains);
// remove(); 将指定的对象从集合中删除
list.remove(p1);
// clear() 清空集合中的所有元素
list.clear();
System.out.println(list);
}
2.2.List
元素可以重复,允许在指定位置插入元素,并通过索引来访问元素
2.2.1 List集合特有的方法
1:增加
void add(int index, E element) 指定位置添加元素
boolean addAll(int index, Collection c) 指定位置添加集合
2:删除
E remove(int index) 删除指定位置元素
3:修改
E set(int index, E element) 返回的是需要替换的集合中的元素
4:查找:
E get(int index) 注意: IndexOutOfBoundsException
int indexOf(Object o) // 找不到返回-1
lastIndexOf(Object o)
5:求子集合
List<E> subList(int fromIndex, int toIndex) // 不包含toIndex
2.2.2. ArrayList
ArrayList 底层采用数组实现,默认10。每次增长60%,((oldCapacity * 3)/2 + 1) 查询快,增删慢。
练习:去除ArrayList集合中重复元素
1:存入字符串元素
2:存入自定义对象元素(如Perosn对象)
原理:
循环遍历该集合,每取出一个放置在新的集合中,放置之前先判断新的集合是否以包含了新的元素。
public class Demo6 {
public static void main(String[] args) {
ArrayList arr = new ArrayList();
Person p1 = new Person("jack", 20);
Person p2 = new Person("rose", 18);
Person p3 = new Person("rose", 18);
arr.add(p1);
arr.add(p2);
arr.add(p3);
System.out.println(arr);
ArrayList arr2 = new ArrayList();
for (int i = 0; i < arr.size(); i++) {
Object obj = arr.get(i);
Person p = (Person) obj;
if (!(arr2.contains(p))) {
arr2.add(p);
}
}
System.out.println(arr2);
}
}
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object obj) {
Person p = (Person) obj;
return this.name.equals(p.name) && this.age == p.age;
}
@Override
public String toString() {
return "Person@name:" + this.name + " age:" + this.age;
}
}
2.2.3. LinkedList
LinkedList 底层采用链表实现,增删快,查询慢。
特有方法:
1:方法介绍
addFirst(E e) //添加到第一位
addLast(E e) //添加到末尾
getFirst() //获取第一位元素的内容
getLast() //获取最后一位元素的内容
removeFirst() //删除第一位元素
removeLast() //删除最后一位元素
如果集合中没有元素,获取或者删除元素抛异常:NoSuchElementException
2:数据结构
1:栈 (1.6)
先进后出
push()
pop()
2:队列(双端队列1.5)
先进先出
offer()
poll()
3:返回逆序的迭代器对象
descendingIterator() 返回逆序的迭代器对象
2.3. 迭代器 Iterable
简洁:
Jdk1.5之后添加的新接口, Collection的父接口. 实现了Iterable的类就是可迭代的.并且支持增强for循环。该接口只有一个方法即获取迭代器的方法iterator() 可以获取每个容器自身的迭代器Iterator。
Iterator接口定义的方法
Itreator 该接口是集合的迭代器接口类,定义了常见的迭代方法
1:boolean hasNext()
判断集合中是否有元素,如果有元素可以迭代,就返回true。
2: E next()
返回迭代的下一个元素,注意: 如果没有下一个元素时,调用
next元素会抛出NoSuchElementException
3: void remove()
从迭代器指向的集合中移除迭代器返回的最后一个元素(可选操作)。
迭代器的遍历
while循环
public static void main(String[] args) {
ArrayList list = new ArrayList();
// 增加:add() 将指定对象存储到容器中
list.add("计算机网络");
list.add("现代操作系统");
list.add("java编程思想");
list.add("java核心技术");
list.add("java语言程序设计");
System.out.println(list);
Iterator it = list.iterator();
while (it.hasNext()) {
String next = (String) it.next();
System.out.println(next);
}
}
for循环
import java.util.ArrayList;
import java.util.Iterator;
public class Demo2 {
public static void main(String[] args) {
ArrayList list = new ArrayList();
// 增加:add() 将指定对象存储到容器中
list.add("计算机网络");
list.add("现代操作系统");
list.add("java编程思想");
list.add("java核心技术");
list.add("java语言程序设计");
System.out.println(list);
for (Iterator it = list.iterator(); it.hasNext();) {
//迭代器的next方法返回值类型是Object,所以要记得类型转换。
String next = (String) it.next();
System.out.println(next);
}
}
}
使用迭代器清空集合
public class Demo1 {
public static void main(String[] args) {
Collection coll = new ArrayList();
coll.add("aaa");
coll.add("bbb");
coll.add("ccc");
coll.add("ddd");
System.out.println(coll);
Iterator it = coll.iterator();
while (it.hasNext()) {
it.next();
it.remove();
}
System.out.println(coll);
}
}
细节一:
如果迭代器的指针已经指向了集合的末尾,那么如果再调用next()会返回NoSuchElementException异常
细节二:
如果调用remove之前没有调用next是不合法的,会抛出IllegalStateException
注意
在对集合进行迭代过程中,不允许出现迭代器以外的对元素的操作,因为这样会产生安全隐患,java会抛出异常并发修改异常(ConcurrentModificationException),普通迭代器只支持在迭代过程中的删除动作。
List特有的迭代器ListIterator
ListIterator Iterator子接口 List专属的迭代器
add(E e) 将指定的元素插入列表(可选操作)。该元素直接插入到 next 返回的下一个元素的前面(如果有)
void set(E o) 用指定元素替换 next 或 previous 返回的最后一个元素
hasPrevious() 逆向遍历列表,列表迭代器有多个元素,则返回 true。
previous() 返回列表中的前一个元素。
Iterator在迭代时,只能对元素进行获取(next())和删除(remove())的操作。对于 Iterator 的子接口ListIterator 在迭代list 集合时,还可以对元素进行添加(add(obj)),修改set(obj)的操作。
倒序遍历
import java.util.ArrayList;
import java.util.ListIterator;
public class Demo2 {
public static void main(String[] args) {
ArrayList list = new ArrayList();
// 增加:add() 将指定对象存储到容器中
list.add("计算机网络");
list.add("现代操作系统");
list.add("java编程思想");
list.add("java核心技术");
list.add("java语言程序设计");
System.out.println(list);
// 获取List专属的迭代器
ListIterator lit = list.listIterator();
while (lit.hasNext()) {
String next = (String) lit.next();
System.out.println(next);
}
System.out.println("***************");
while (lit.hasPrevious()) {
String next = (String) lit.previous();
System.out.println(next);
}
}
}
网友评论