【集合概述】【迭代器】【Vector中的枚举】【List集合】【LinkList】【ArrayList】
集合类Collection
集合是存储对象的容器,以便于对多个对象进行操作
集合与数组的区别
数组也可以存储对象,但是长度固定,集合的长度可变
数组还可以存储基本数据类型,集合只能存储对象
集合的特点:
只用于存储对象,且可以存储不同类型的对象,长度可变
集合框架
集合相关的API可以分为三类:接口(Interface)、实现类(Implementation)、抽象类(Abstract)
这些API统称为集合框架(Collection Framework),存放在jav.util包中,所以在使用时要导入java.util包
集合框架中存在多个容器,每一个容器对数据的存储方式都不同,这种存储方式称为:数据结构
v常用操作示例:
共性方法
import java.util.*; //使用了包中的方法,要先导包 class CollectionDemo { public static void sop(Object obj) { System.out.println(obj); } public static void main(String[] args) { //base_method(); //method_2(); method_get(); } public static void method_get() { ArrayList a1 = new ArrayList(); a1.add("java1"); a1.add("java2"); a1.add("java3"); //接口型引用,通过集合中的方法 Iterator it = a1.iterator();//获取迭代器,用于取出集合中元素 while (it.hasNext())//若果仍有元素可迭代返回真,false则跳出循环 { sop(it.next()); } } public static void method_2()//交集 { ArrayList a1 = new ArrayList(); a1.add("java1"); a1.add("java2"); a1.add("java3"); ArrayList a2 = new ArrayList(); a2.add("java1"); a2.add("java8"); a2.add("java6"); //a1.retainAll(a2); //取交集,a1中只保留和a2中相同的元素 a1.removeAll(a2); //去交集,a1中只保留和a2中不同的元素 sop("a1="+a1); sop("a2="+a2); } public static void base_method() { ArrayList a = new ArrayList();//创建一个集合容器,使用Collection接口的子类ArrayList a.add("java1"); //1、添加元素 a.add("java2"); //add(Object obj);多态性 a.add("java3"); sop(a); //打印原集合 sop("size="+a.size()); //2、获取元素个数 //a.remove("java3"); //3、删除元素 //a.clear(); // 清空集合 //4、判断元素 sop("java3是否存在:"+a.contains("java3")); sop("集合是否为空 :"+a.isEmpty()); sop(a); } }【小结】
1,add方法参数为Object,多态性,以便于接受任意类型对象
2,集合中存储的都是对象的引用()
3,集合可以直接打印
Iterator接口,迭代器
集合中取出元素的方式
元素的取出方式定义在集合内部(内部类),以便于直接访问集合元素
每一个容器的数据结构不同,所以取出的动作细节也不一样。但是都有共性内容判断hasNext()、取出.next();
向上抽取出来一个规则:Iterator;采用内部类的设计,通过一个对外提供的方法iterator(); 获取集合对象
Collection
|——List:元素是有序的,可以重复,因为该集合体系有索引;常见的子类对象:
|————ArrayList:数据结构是数组结构;特点:查询速度很快,但是增删稍慢;线程不同步
|————LinkedList:链表数据结构;特点:查询较慢,增删很快
|————Vector: 数组数据结构;线程同步;慢;被ArrayList替代了
——Set:元素是无序的,不能重复
List 特有方法,凡是可以操作角标的方法都是该体系特有方法
增
——add(index,element);
——addAll(index,Collection);
删
——remove(index);
改
——set(index,element);
查
——get(index):
——subList(from,to);
——listIterator();
——int indexOf(obj):获取指定元素的位置。
——ListIterator listIterator();
List集合特有的迭代器。ListIterator是Iterator的子接口。
在迭代时,不可以通过集合对象的方法操作集合中的元素。因为会发生ConcurrentModificationException异常。
所以,在迭代器时,只能用迭代器的方法操作元素,可是Iterator方法是有限的,只能对元素进行判断,取出,删除的操作,
如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator。该接口只能通过List集合的listIterator方法获取。
List集合共性方法
import java.util.*; class ListDemo { public static void sop(Object obj) { System.out.println(obj); } public static void main(String[] args) { ArrayList a1 = new ArrayList(); a1.add("java1"); a1.add("java2"); a1.add("java3"); sop("原集合:"+a1); ListIterator li = a1.listIterator();//更加强大 while (li.hasNext()) { Object obj = li.next(); if (obj.equals("java2")) //li.add("java007");//添加 li.set("java008"); //修改 } while (li.hasPrevious()) //如果前面有元素则返回true { sop("pre:"+li.previous());//反向获取 } /* Iterator it = a1.iterator(); //迭代器,在迭代过程中,准备添加或删除元素 while (it.hasNext()) //只能查,删,不能添加修改 { Object obj = it.next(); if (obj.equals("java2")) it.remove(); //集合中持有的只是对象的引用,删除的也只是引用 sop("obj="+obj); //remove后对象并没有删除,所以obj的指向时仍有效 }*/ sop(a1); } public static void method() { ArrayList a1 = new ArrayList(); a1.add("java1"); a1.add("java2"); a1.add("java3"); sop("原集合:"+a1); a1.add(2,"java08"); //在指定位置添加元素 a1.remove(1); //删除指定角标元素 a1.set(2,"java007");//修改指定角标元素 sop("get(1)"+a1.get(1));//通过角标获取元素 sop(a1); for (int x =0; x<a1.size() ;x++ )//获取所有元素 { // sop("a1("+x+")="+a1.get(x)); } Iterator it = a1.iterator(); //迭代器 while (it.hasNext()) { sop("next:"+it.next()); } sop("index="+a1.indexOf("java007"));//通过indexOf获取对象的位置 List sub = a1.subList(0,2); //包含头不包含尾 sop("sub="+sub); } }
Vector中的枚举
elements
Enumeration en = v.elements(); while (en.hasMoreElements) { System.out.println(en.nextElement()); }//枚举就是Vector特有的取出方式,枚举和迭代是一样的,被迭代器取代
//因为枚举名称及方法的名称都过长,所以被迭代器取代了
LinkedList:特有方法
addFirst();
addLast();
getFirst();
getLast();
removeFirst();
removeLast();
如果列表为空,会抛出:NoSuchElementException
JDK1.6出现的替代方法
如果列表为空,会返回null
offerFirst();
offerLast();
peekFirst();
peekLast();
pollFirst();
pollLast();
LinkList操作
import java.util.*; class LinkedListDemo { public static void sop (Object obj) { System.out.println(obj); } public static void main(String[] args) { LinkedList link = new LinkedList(); link.addFirst("java1"); link.addLast("java2"); //在上一个元素尾部添加 link.addFirst("java3"); //在上一个元素头部添加 link.addFirst("java4"); sop(link); sop(link.getFirst()); //获取链表头部元素,不删除 sop(link.getLast()); //获取链表尾部元素 sop(link.removeFirst());//获取并删除元素,长度改变 sop(link.removeFirst());//可以重复出现 sop("size="+link.size());//获取链表长度 while (!link.isEmpty()) { sop(link.removeFirst()); } } }
使用LinkedList模拟一个堆栈或队列数据结构
堆栈:先进后出 杯子
队列:先进先出 水管示例:
class DuiLie { private LinkedList link; DuiLie() { link = new LinkedList(); } public void myAdd(Object obj) { link.addFirst(obj); // } public Object myGet() { //return link.removeLast();//先进先出 return link.removeFirst();//后进先出 } public boolean isNull() { return link.isEmpty(); } }
取出ArrayList集合中的重复元素
public static ArrayList singleElement(ArrayList al) { ArrayList newAl = new ArrayList();//临时容器 Iterator it = al.iterator(); //迭代数组al的元素 while (it.hasNext()) { Object obj = it.next(); if (!newAl.contains(obj)) //如果newAl中不包含该元素,则存入;如果重复则跳过 newAl.add(obj); } return newAl; // }
将自定义对象作为元素存储到ArrayList集合中,并去除重复元素
比如:人对象,同姓名同年龄就视为同一个人;作为重复元素
思路:
1,对人进行描述,封装对象
2,定义容器,将人存入
3,取出
ArrayList操作
import java.util.*; class Person { private String name; private int age; Person(String name,int age) { this.name = name; this.age = age; } public boolean equals(Object obj)//复写equals方法 { if (!(obj instanceof Person)) //健壮性判断;一元运算符!要加括号 return false; Person p = (Person)obj; //类型向下强转 return this.name.equals(p.name) && this.age==p.age;//字符串的equals方法 } public String getName() { return name; } public int getAge() { return age; } } class ArrayListTest2 { public static void sop(Object obj) { System.out.println(obj); } public static void main(String[] args) { ArrayList al = new ArrayList(); al.add(new Person("list001",23));//al.add(Object obj);多态性,不能直接访问子类Person特有方法 al.add(new Person("list002",22)); //Object obj = new Person("list002",22); al.add(new Person("list003",25)); al.add(new Person("list003",25)); al.add(new Person("list004",27)); al.add(new Person("list004",27)); //al = singleElement(al); sop("remove 03:"+al.remove(new Person("list003",25)));//打印true说明在删除元素时要先equals判断是否存在 Iterator it = al.iterator(); while (it.hasNext()) { Person p = (Person)it.next(); //必须向下转型 才能访问Person类的特有方法 sop(p.getName()+"..."+p.getAge()); } } public static ArrayList singleElement(ArrayList al) { ArrayList newAl = new ArrayList();//临时容器 Iterator it = al.iterator(); //迭代数组al的元素 while (it.hasNext()) { Object obj = it.next(); if (!newAl.contains(obj)) //如果newAl中不包含该元素,则存入;如果重复则跳过 newAl.add(obj); //contains()调用的是equals方法 } return newAl; // } }
【小结】
List元素判断元素是否相同,依据的是equals方法;ArrayList、LinkedList都是依赖于equals进行判断contains()的判断调用了equals方法,默认调用的是Object的equals方法,每一个元素的调次数 是由临时容器中的元素个数决定的;
String类中复写了equals,所以在判断时函数自动覆盖,不需要再复写;字符串对象(以及基本数据类型对象)都在类中复写了equals
而用对象做比较时,如果该类没有复写equals方法,默认调用的是Object的equals;判断的是对象的地址值(即是否同一个对象);而如果判断的是对象的属性是否重复,所以要复写equals方法,使contains调用时默认重载
在remove()对象时,也会调用equals()方法,如果该对象的类中复写了equals(),调用时覆盖,打印出true(如示例所示)
如果该类中没有复写equals() 则打印出false,因为调用的是Object中的equals方法
要重视运算符的作用,灵活运用!
实际使用中ArrayList用的比较多,因为一般数据查询的操作比较多