java集合关系图
上述类图中,实线边框的是实现类,比如ArrayList,LinkedList,HashMap等;折线边框的是抽象类,比如AbstractCollection,AbstractList,AbstractMap等;而点线边框的是接口,比如Collection,Iterator,List等。
1、Iterator接口
Iterator接口,这是一个用于遍历集合中元素的接口,主要包含hashNext(),next(),remove()三种方法。它的一个子接口LinkedIterator在它的基础上又添加了三种方法,分别是add(),previous(),hasPrevious()。也就是说如果是先Iterator接口,那么在遍历集合中元素的时候,只能往后遍历,被遍历后的元素不会在遍历到,通常无序集合实现的都是这个接口,比如HashSet,HashMap;而那些元素有序的集合,实现的一般都是LinkedIterator接口,实现这个接口的集合可以双向遍历,既可以通过next()访问下一个元素,又可以通过previous()访问前一个元素,比如ArrayList。
抽象类的使用。如果要自己实现一个集合类,去实现那些抽象的接口会非常麻烦,工作量很大。这个时候就可以使用抽象类,这些抽象类中给我们提供了许多现成的实现,我们只需要根据自己的需求重写一些方法或者添加一些方法就可以实现自己需要的集合类,工作流昂大大降低。
2、Collection (集合的最大接口)继承关系
——List 可以存放重复的内容
——Set 不能存放重复的内容,所以的重复内容靠hashCode()和equals()两个方法区分
——Queue 队列接口
——SortedSet 可以对集合中的数据进行排序
Collection定义了集合框架的共性功能。
add方法的参数类型是Object。以便于接收任意类型对象。
集合中存储的都是对象的引用(地址)。
package 集合;
import java.util.ArrayList;
import java.util.Iterator;
/*
Collection定义了集合框架的共性功能。
1,添加
add(e);
addAll(collection);
2,删除
remove(e);
removeAll(collection);
clear();
3,判断。
contains(e);
isEmpty();
4,获取
iterator();
size();
5,获取交集。
retainAll();
6,集合变数组。
toArray();
1,add方法的参数类型是Object。以便于接收任意类型对象。
2,集合中存储的都是对象的引用(地址)
什么是迭代器呢?
其实就是集合的取出元素的方式。
如同抓娃娃游戏机中的夹子。
迭代器是取出方式,会直接访问集合中的元素。
所以将迭代器通过内部类的形式来进行描述。
通过容器的iterator()方法获取该内部类的对象。
*/
public class CollectionDemo {
public static void main(String[] args) {
// base_method();
// method_2();
method_get();
}
public static void method_get(){
ArrayList al = new ArrayList();
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
al.add("java04");
// 获取迭代器,用于取出集合中的元素
Iterator it = al.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
// 另一种写法。
for(Iterator it1 = al.iterator();it1.hasNext();){
System.out.println(it1.next());
}
}
public static void base_method() {
// 创建一个集合容器。使用Collection 接口的子类。ArrayList()
// 因为Collection 中的方法是子类所共有的
ArrayList al = new ArrayList();
//1.添加元素
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
ArrayList al2 = new ArrayList();
al2.add("aa");
al2.add(al); // 也可添加一个集合
// 打印集合
System.out.println(al2); // [aa, [java01, java02, java03, java04]]
System.out.println("原集合:"+al); // 原集合:[java01, java02, java03, java04]
//2.获取
System.out.println("集合的大小:"+al.size()); // 4
//3.判断
System.out.println("java03是否存在:"+al.contains("java03")); // ture
System.out.println("集合是否为空:"+al.isEmpty()); // false
//4.删除元素
al.remove("java02");
System.out.println("删除后的集合:"+al); // 删除后的集合:[java01, java03, java04]
al.clear();
System.out.println("清空后的集合:"+al); // 清空后的集合:[]
}
public static void method_2(){
ArrayList al1 = new ArrayList();
al1.add("java01");
al1.add("java02");
al1.add("java03");
al1.add("java04");
ArrayList al2 = new ArrayList();
al2.add("java03");
al2.add("java04");
al2.add("java05");
al2.add("java06");
al1.retainAll(al2); // 去交集,al1只保留与al2的交集 al1:[java03, java04]
al2.removeAll(al1); // 一出al2 中al1的所有 al2:[java05, java06]
System.out.println("al1:"+al1);
System.out.println("al2:"+al2);
}
}
3、List的常用子类(有特有的迭代器)
特有方法。凡是可以操作角标的方法都是该体系特有的方法。
——ArrayList 底层是数组结构,线程不安全,查询速度快,但是增删慢
——Vector 底层是数组结构,线程安全,但速度慢,已被ArrayList替代
——LinkedList 底层是链表结构,增删速度快,查询慢
ArraylList示例:
/*
List集合特有的迭代器。ListIterator是Iterator的子接口。
在迭代时,不可以通过集合对象的方法操作集合中的元素。
因为会发生ConcurrentModificationException异常。
所以,在迭代器时,只能用迭代器的放过操作元素,可是Iterator方法是有限的,
只能对元素进行判断,取出,删除的操作,
如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator。
该接口只能通过List集合的listIterator方法获取。
*/
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class ListDemo {
public static void main(String[] args) {
// method();
method_1();
}
public static void method(){
ArrayList al = new ArrayList();
// 添加元素
al.add("java01");
al.add("java02");
al.add("java03");
System.out.println("原集合="+al); // 原集合=[java01, java02, java03]
al.add(1,"java99"); // 指定位置添加元素
System.out.println(al); // [java01, java99, java02, java03]
//
al.remove(1); // 删除索引为1的元素
System.out.println(al); // [java01, java02, java03]
al.set(2,"python");
System.out.println(al); // [java01, java02, python]
Object res = al.get(1); // 获取某个索引的元素
System.out.println(res); // java02
// 获取所有的元素
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
List al2 = al.subList(1,3); // 返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。
System.out.println(al2); // [java02, python]
int i = al.indexOf("java02"); //获取指定对象的索引
System.out.println(i);
}
public static void method_1(){
ArrayList al = new ArrayList();
// 添加元素
al.add("java01");
al.add("java02");
al.add("java03");
System.out.println("原集合="+al); // 原集合=[java01, java02, java03]
// 问题引出
// Iterator it = al.iterator();
// while (it.hasNext()){
// if(it.next() == "java02")
// al.add("java99"); // 这时会抛出java.util.ConcurrentModificationException
// }
/*问题原因:
当al集合在被访问时,不能被增删改的,因为Arraylist是不同步的
当然我们可以用迭代器对其进行操作,然而,Iterator 中只有remove()方法
这时,就出现了ListIterator接口(只有List方法实现类该接口) 可对集合进行增删改查
* */
ListIterator lit = al.listIterator();
while (lit.hasNext()){
if(lit.next()=="java02"){
//lit.add("java99"); // 添加
lit.set("java0222"); // 修改 next()这个对象
//lit.remove(); // 删除next()对象
}
}
// 逆向输出
while (lit.hasPrevious()){ // hasPrevious() 前一个索引有没有对象
System.out.println(lit.previous());
}
System.out.println(al); // [java01, java02, java99, java03]
}
}
LinkedList示例
import java.util.LinkedList;
/*
LinkedList:特有方法:
addFirst();
addLast();
getFirst();
getLast();
获取元素,但不删除元素。如果集合中没有元素,会出现NoSuchElementException
removeFirst();
removeLast();
获取元素,但是元素被删除。如果集合中没有元素,会出现NoSuchElementException
在JDK1.6出现了替代方法。
offerFirst();
offerLast();
peekFirst();
peekLast();
获取元素,但不删除元素。如果集合中没有元素,会返回null。
pollFirst();
pollLast();
获取元素,但是元素被删除。如果集合中没有元素,会返回null。
*/
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList ll = new LinkedList();
// 从头部添加
ll.addFirst("java01");
ll.addFirst("java02");
ll.addFirst("java03");
ll.addFirst("java04");
System.out.println(ll); // [java04, java03, java02, java01]
System.out.println(ll.getFirst()); // 获取头部对象 java04 1.6 的被 peekFirst(); 替代
System.out.println(ll.getFirst()); // java04
System.out.println(ll.getLast()); // 获取尾部对象 java01
System.out.println(ll.removeFirst()); // 删除第一个对象 1.6 的被 pollFirst(); 替代
System.out.println(ll); // [java03, java02, java01]
while (!ll.isEmpty()){
System.out.println(ll.removeLast()); // 遍历并删除
}
}
}
ArrayList练习
import java.util.ArrayList;
import java.util.Iterator;
// 去除Arraylist 集合中重复项
public class ArrayListTest1 {
public static void main(String[] args) {
ArrayList al = new ArrayList();
al.add("java1");
al.add("java1");
al.add("java2");
al.add("java3");
al.add("java3");
al.add("java5");
ArrayList al1 = quchong(al);
System.out.println(al1);
}
public static ArrayList quchong(ArrayList list){
ArrayList al = new ArrayList();
Iterator it = list.iterator();
while (it.hasNext()){
// 如果新集合中不包含该对象
Object obj = it.next();
if(!al.contains(obj)){
al.add(obj);
}
}
return al;
}
}
练习2(List集合判断元素是否相同,依据是元素的equals方法。)
import java.util.ArrayList;
import java.util.Iterator;
/*
将自定义对象作为元素存到ArrayList集合中,并去除重复元素。
比如:存人对象。同姓名同年龄,视为同一个人。为重复元素。
思路:
1,对人描述,将数据封装进人对象。
2,定义容器,将人存入。
3,取出。
List集合判断元素是否相同,依据是元素的equals方法。1
*/
public class ArrayListTest2 {
public static void main(String[] args) {
ArrayList al = new ArrayList();
al.add(new Person("xiaoming",20));
al.add(new Person("lisi",25));
al.add(new Person("lisi",25));
ArrayList al1 = quchong(al);
for (Iterator it = al1.iterator();it.hasNext();){
System.out.println(it.next());
}
}
public static ArrayList quchong(ArrayList list){
ArrayList al = new ArrayList();
Iterator it = list.iterator();
while (it.hasNext()){
//contains() 会调用Object下的equals()默认比较的时地址,所以需要重写该方法
// 底层就是传入的对象与al里的每个对象进行比较 obj.equals(al里的每个对象)
Object obj = it.next();
if(!al.contains(obj)){
al.add(obj);
}
}
return al;
}
}
class Person{
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public boolean equals(Object o){
if(!(o instanceof Person)){
return false;
}
Person p = (Person)o;
System.out.println(this.name+".equals"+p.name);
return this.name == p.name && this.age == p.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 String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}