集合
1-Collection接口
2021-07-09 677 1
简介 Java集合中的重要结构,Collection中的重要方法。
1. 集合概述
面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,就要对对象进行存储。使用Array存储对象方面具有一些弊端,而Java 集合就像一种容器,可以动态地把多个对象的引用放入容器中。
数组在内存存储方面的特点:
数组初始化以后,长度就确定了。
数组声明的类型,就决定了进行元素初始化时的类型
数组在存储数据方面的弊端:
数组初始化以后,长度就不可变了,不便于扩展
数组中提供的属性和方法少,不便于进行添加、删除、插入等操作, 且效率不高。同时无法直接获取存储元素的个数
数组存储的数据是有序的(顺序存储的)、可以重复的。存储数据的类型单一
Java 集合类可以用于存储数量不等的多个对象,还可用于保存具有映射关系的关联数组。
1.集合、数组都是对多个数据进行存储操作的结构,简称Java容器。
说明:此时的存储,主要指的是内存层面的存储,不涉及到持久化的存储(.txt,.jpg,.avi,数据库中)
2.1 数组在存储多个数据方面的特点:
> 一旦初始化以后,其长度是确定的。
> 数组一旦定义好,其元素的类型也是确定的,只能操作指定类型的数据,比如:String[] arr;int[] arr1;Object[] arr2;
2.2 数组在存储多个数据方面的缺点:
> 一旦初始化以后,其长度就不可修改
> 数组中提供的方法非常有限,对于添加、删除、插入数据等操作,非常不便,同时效率不高。
> 获取数组中实际元素的个数的需求,数组没有现成的属性或方法可用
> 数组存储数据的特点:顺序存储的、可重复。对于无序存储、不可重复的需求,不能满足,而如果使用容器中的Map可解决。
Java 集合类可以用于存储数量不等的多个对象,还可用于保存具有映射关系的关联数组,并提供了丰富的方法用于操作容器中的数据。
2. 集合中的重要结构
二、集合框架
|----Collection接口:单列集合,用来存储一个一个的对象
|----List接口:存储有序的、可重复的数据,“动态”数组,可动态扩容
|----ArrayList、LinkedList、Vector
|----Set接口:存储无序的、不可重复的数据,类比于高中学的“集合”(有限性、确定性、互异性、无序性)
|----HashSet、LinkedHashSet、TreeSet
|----Map接口:双列集合,用来存储一对(key - value)一对的数据,类比高中学习的函数:y = f(x)
|----HashMap、LinkedHashMap、TreeMap、Hashtable、Properties
3. Collection接口方法的使用
3.1 add() 、 size() 、 addAll()、 clear()、 isEmpty() 方法的使用
@Test
public void testColl(){
Collection coll = new ArrayList();
// boolean add(E e);
coll.add(123);
coll.add('a');
coll.add("ylaihui");
// size() 返回元素的个数
System.out.println(coll.size()); // 3
Collection coll2 = new ArrayList();
coll2.add(new java.lang.String("ylaihui"));
coll2.add(new java.lang.StringBuffer("ylaihui"));
//addAll(Collection coll1):将coll1集合中的元素添加到当前的集合中
coll.addAll(coll2);
System.out.println(coll.size()); // 5
// 调用 ArrayList的 toString方法 [123, a, ylaihui, ylaihui, ylaihui]
System.out.println(coll);
// 判断集合是否为空 (集合中是否有元素) return size() == 0
Collection coll3 = new ArrayList();
System.out.println(coll3.isEmpty()); // true
System.out.println(coll.isEmpty()); // false
// 清空集合元素
coll.clear();
System.out.println(coll.isEmpty()); // true
}
代码输出:
3
5
[123, a, ylaihui, ylaihui, ylaihui]
true
false
true
3.2 contains()、 containsAll()、 remove()、removeAll()方法的使用
order类
class Order {
private int id;
private double price;
public Order() {
}
public Order(int id, double price) {
this.id = id;
this.price = price;
}
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Order order = (Order) o;
return id == order.id &&
Double.compare(order.price, price) == 0;
}
public String toString() {
return "Order{" +
"id=" + id +
", price=" + price +
'}';
}
}
@Test
public void testMethod() {
Collection objects = new ArrayList();
objects.add(123);
objects.add(false);
objects.add(new String("ylaihui"));
// contains(Object obj):判断当前集合中是否包含obj
// 会调用obj对象所在类的equals(),并非比较的对象的地址,而是比较的对象的内容
System.out.println(objects.contains(123)); // 自动装箱 true
System.out.println(objects.contains("ylaihui")); // true
System.out.println(objects.contains(new String("ylaihui"))); // true
Order order = new Order(111, 100.00);
objects.add(order);
// 不管有没有重写equals,结果都为true,因为是同一个对象 调用== 或 equals都是true
System.out.println(objects.contains(order)); // true
// true, 如果Order类没有重写equals方法,结果为 false
System.out.println(objects.contains(new Order(111, 100.00))); // true
Collection coll1 = Arrays.asList(123, false);
// 判断 objects 集合中是否包含集合 coll1, 子集的关系
System.out.println(objects.containsAll(coll1)); // true
// remove(Object obj):从当前集合中移除obj元素。
objects.remove(new Order(111, 100.00));
System.out.println(objects); // [123, false, ylaihui]
//removeAll():移除两个部分的交集(coll2和objects的交集被移除)
Collection coll2 = Arrays.asList(123, false, 1111);
objects.removeAll(coll2);
System.out.println(objects); // [ylaihui]
}
3.3 retainAll() 方法的使用
@Test
public void test3() {
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new Order(1111, 100.00));
coll.add(new String("ylaihui"));
coll.add(false);
//retainAll(Collection coll1):交集:获取当前集合和coll1集合的交集,并返回给当前集合
Collection coll1 = Arrays.asList(123, 456, 789);
coll.retainAll(coll1);
System.out.println(coll); // [123, 456]
}
3.4 equals() 方法的使用
@Test
public void test4() {
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new Order(1111, 100.00));
coll.add(new String("ylaihui"));
coll.add(false);
Collection coll2 = new ArrayList();
coll2.add(123);
coll2.add(456);
coll2.add(new Order(1111, 100.00));
coll2.add(new String("ylaihui"));
coll2.add(false);
//equals(Object obj):要想返回true,需要当前集合和形参集合的元素都相同。
System.out.println(coll.equals(coll2)); // true
}
3.5 toArray()、hashCode()、 Arrays.asList()
@Test
public void test5() {
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new Order(1111, 100.00));
coll.add(new String("ylaihui"));
coll.add(false);
//hashCode():返回当前对象的哈希值
System.out.println(coll.hashCode());
//集合 -> 数组:toArray()
Object[] objects = coll.toArray();
for (int i = 0; i < objects.length; i++) {
System.out.println(objects[i]);
}
//数组 -> 集合:调用Arrays类的静态方法asList(),基本数据类型的数组无法转换为多元素的集合
Collection coll2 = Arrays.asList(objects);
System.out.println(coll2); // [[123, 456, Order{id=1111, price=100.0}, ylaihui, false]]
System.out.println("coll2.size() = " + coll2.size()); // 5
Collection coll3 = Arrays.asList(new String[]{"y", "lai", "hui"});
System.out.println(coll3); // [y, lai, hui]
System.out.println(coll3.size()); // 3
Collection coll4 = Arrays.asList(new int[]{1, 2, 3});
System.out.println(coll4); // [[I@22927a81]
System.out.println(coll4.size()); // 1
Collection coll5 = Arrays.asList(new Integer[]{1, 2, 3});
System.out.println(coll5); // [1, 2, 3]
System.out.println(coll5.size()); // 3
}
3.6 iterator() 方法的使用
Iterator对象称为迭代器(设计模式的一种),主要用于遍历 Collection 集合中的元素。
GOF给迭代器模式的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。 迭代器模式,就是为容器而生。 类似于“公交车上的售票员”、“火车上的乘务员”、 “空姐” 。
Collection接口继承了java.lang.Iterable接口,该接口有一个iterator()方法,那么所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了
Iterator接口的对象。
Iterator 仅用于遍历集合, Iterator 本身并不提供承装对象的能力。如果需要创建Iterator 对象,则必须有一个被迭代的集合。
集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。
在调用it.next()方法之前必须要调用it.hasNext()进行检测。若不调用,且
下一条记录无效,直接调用it.next()会抛出NoSuchElementException异常。
@Test
public void testIterator(){
Collection coll = new ArrayList();
coll.add(123);
coll.add(234);
coll.add("ylaihui");
Iterator iterator = coll.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
// 迭代器遍历结束后,需要重新初始化 否则报异常 NoSuchElementException
// 可以这样实现,但是不推荐这么使用
iterator = coll.iterator();
for (int i = 0; i < coll.size(); i++) {
System.out.println(iterator.next());
}
}
3.7 iterator() 方法的原理
调用 next() 时指针下移
每次调用 Iterator() 方法都会返回一个 Iterator 对象
System.out.println(iterator.getClass()); 对于ArrayList集合的迭代器, 是其内部类的类型, class java.util.ArrayList$Itr,该内部类实现了 Iterator接口
4. 迭代器的remove()方法
如果还未调用next()或在上一次调用 next 方法之后已经调用了 remove 方法,
再调用remove都会报IllegalStateException。
public class IteratorRemove {
@Test
public void testremove(){
Collection coll = new ArrayList();
coll.add(111);
coll.add(222);
coll.add("ylaihui");
Iterator it = coll.iterator();
while(it.hasNext()){
Object next = it.next();
if(next.equals(111)){
it.remove();
}
}
it = coll.iterator();
while (it.hasNext())
System.out.println(it.next());
}
}
代码运行结果
222
ylaihui
5. foreatch 增强for循环
jdk 5.0 新增了foreach循环,用于遍历集合、数组
for(集合元素的类型 局部变量 : 集合对象)
内部仍然调用了迭代器。
//ForeatchTest.java
package com.ylaihui.collectionitf;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
public class ForeatchTest {
public void testremove() {
Collection coll = new ArrayList();
coll.add(111);
coll.add(222);
coll.add("ylaihui");
for(Object obj : coll){
System.out.println(obj);
}
}
public void testArray(){
int[] ints = {1, 2, 3, 4, 5};
for(int i : ints){
System.out.println(i);
}
}
}