【集合概述】【迭代器】【Vector中的枚举】【List集合】【LinkList】【ArrayList】

时间:2021-02-23 04:26:45



集合类Collection

集合是存储对象的容器,以便于对多个对象进行操作

集合与数组的区别

数组也可以存储对象,但是长度固定,集合的长度可变

数组还可以存储基本数据类型,集合只能存储对象

集合的特点:

只用于存储对象,且可以存储不同类型的对象,长度可变

集合框架

集合相关的API可以分为三类:接口(Interface)、实现类(Implementation)、抽象类(Abstract)

这些API统称为集合框架(Collection Framework),存放在jav.util包中,所以在使用时要导入java.util包

集合框架中存在多个容器,每一个容器对数据的存储方式都不同,这种存储方式称为:数据结构

【集合概述】【迭代器】【Vector中的枚举】【List集合】【LinkList】【ArrayList】

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用的比较多,因为一般数据查询的操作比较多