我们知道:
Collection:可以这样理解:Collection是存储所有对象集合的一个大容器,它是一个接口,是集合对象的老大哥!其下有两个得力助手,那就是LIst 和 Set,两个助手各有各自的高深本领!如下所示:
(1)List的本领:它召集的小弟们(类对象或者说是类中的元素也行)全是有序排列的,可以重复,每个小弟都有一个编号,随时呼唤,随时出现在眼前;
(2)Set的本领:它的小弟们(类对象或者是类中的元素)更牛,全无序排列,每个小弟都是独一无二的,不可以重复!
两个助手的本例也有共同点:那就是都能
“召集新的兄弟(增加的方法)”
“整顿兄弟(修改的方法)”
“干掉兄弟(删除的方法)”
“深入了解某一个兄弟(查看的方法)”
具体的方法实现不多说了,学java的人都知道在java api帮助文档中都有:在java.util(工具)包中自己查看,学习调用就行!
直接进入正题:
【对于List】实现它的具体类有ArrayList,LinkedList,Vector
用一个代码全部搞定最基本常用的方法:
/*
List下得力助手(已经实现的类)之一:【ArrayList】才表演上级老大些传授下来的武功秘籍(增删改查)
由此:这些基本上都是共性的方法具体看ArrayList中基本的“增删改查”方法演示
*/
<span style="font-size:18px;">import java.util.*;
class CollectionDemo
{
public static void main(String[] args)
{
ArrayList ali=new ArrayList();//创建具体的ArrayList对象
ali.add("java1");
ali.add("java2");
ali.add("java3");
ali.add("");//向该具体的集合中添加元素
ArrayList alj=new ArrayList();
alj.add("java1");
alj.add("");
alj.add("java5");
alj.add("java6");
//添加
addMethod(ali,alj);
//删除
removeMethod(ali,alj);
//修改
updateMethod(ali,alj);
//查看
showMethod(ali,alj);
}
public static void addMethod(ArrayList ali,ArrayList alj)
{
//ali.add("java7"); //指定的元素添加到ali的尾部
//sop(ali); //显示结果:[java1, java2, java3, , java7]
//ali.add(3,"java4");//把指定的元素"java4"添加到指定的角标3位置上
//sop(ali); //显示结果:[java1, java2, java3, , java7]
/*
还有一套类似上述的添加,是对于两个对象之间元素的添加
例如:*/
//ali.addAll(alj);//指定的ArrayList中所有元素添加到ali的尾部
//sop(ali);//[java1, java2, java3, , java1, , java5, java6]
//ali.addAll(3,alj);//指定的ArrayList元素添加到ali的尾部
//sop(ali);//[java1, java2, java3, java1, , java5, java6, ]
}
public static void removeMethod(ArrayList ali,ArrayList alj)
{
//ali.remove("java8");//删除alj中的java3内容,如果内容不存在,就返回false;
//sop(ali.remove("java8"));//false
//ali.remove(1);//是删除指定角标上的位置
//sop(ali);//[java1, java3, ]
//有一个直接删除所有元素的方法:
//ali.clear();
//sop(ali);//结果:[]
//删除一个指定的范围区间:从某指定角标开始到某指定角标结束(注意:结尾角标不在删除的范围中)
/*【注意】
因为removeRange是protected,所以只能ArrayList的子类调用,那就先继承再使用!
ali.removeRange(1,3);这样写法就直接编译失败!以为无法访问!所以写一个ArrayList的子类*/
//单独写了一个子类【MyRemove】去继承ArrayList类,以便能访问这个removeRange函数
//MyRemove my=new MyRemove(ali); //创建子类对象的实例化
//my.getMyRemove(ali,1,3);//结果为:[java1, ]
/*
删除的是1到3角标(不包括3)上的元素,简单总结为“有头无尾”
*/
}
public static void updateMethod(ArrayList ali,ArrayList alj)
{
//ali.set(2,"new java");改变指定角标上的元素
//sop(ali);//[java1, java2, new java, ]
//同理,也可以把ali中2角标上的内容改成alj中所有的元素
//ali.set(2,alj);
//sop(ali);
}
public static void showMethod(ArrayList ali,ArrayList alj)
{
//sop(alj.size());
//sop(alj.get(2));//获取alj角标2上的元素
//sop(ali.isEmpty());
/*
获取索引也很简单就不一一说了:
*/
sop(ali.indexOf("java3"));//2,即是在角标2上的
//同样:查找最后一次出现的位置
ali.lastIndexOf("java2");
//【取两个集合中的交集】
//ali.retainAll(alj);//把ali和alj中的元素交集提取再存入ali中
}
//自己定义一个简化的输出语句的方法,以后直接调用就行,传入类对象,其实就打印出Object类的 toString方法而已!简单实用!!
public static void sop(Object obj)
{
System.out.println(obj);
}
}</span>
是不是很牛,所有的方法都是老大些传授下来的,学会了就直接用就行,威力无比呀!
【注意】但是对于ArrayList本身的removeRange(int fromIndex,int toindex)的方法,是提取角标fromindex到角标toindex-1位置上的元素,这个方法是protected的,必须要写一个子类继承该ArrayList类才能使用:
我为大家写了一个简单的,共大家分享:
ArrayList的【子类】
/*
继承ArrayList,以便访问父类中被protected的removeRange方法:
*/
import java.util.*;
public class MyRemove extends ArrayList
{
//父类中构造函数可以有一个ArrayList对象存在,于是就实例化的同时,添加了新对象进来
public MyRemove(ArrayList ali)
{
super(ali); //实现对该新对象对父类对象的引用
}
//自定义一个获取removeRange方法的功能:
public static void getMyRemove(ArrayList ali,int startIndex,int endIndex)
{
MyRemove mr=new MyRemove(ali);//子类实例化
mr.removeRange(startIndex,endIndex);//在子类中用removeRange方法
ArrayList newAl=(ArrayList)mr;//让它把执行后的结果再返回到ArrayList中
sop("从指定区间中删除后的内容:"+newAl);//打印出元素来即可
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
【基础加强】
要求除去ArrayList中的重复元素
实例分析:
【思路】先自己创建一个新的ArrayList集合
把原来旧的集合中的元素一个一个依次拿去跟新集合中的元素进行比较,如果没有,就添加到新集合中!!
通过迭代的方式打印出来即可……
自己写的代码:
<span style="font-size:18px;"><pre name="code" class="java">import java.util.*;
class DelElementArrayList
{
public static void main(String[] args)
{
ArrayList oldal=new ArrayList();
oldal.add("hello");
oldal.add("hello");
oldal.add("wang");
oldal.add("mingtian");
oldal.add("hello");
oldal.add("wang");
oldal.add("001");
oldal.add("hello");
oldal.add("001");
sop(delMoreElements(oldal));
}
public static ArrayList delMoreElements(ArrayList oldal)
{
ArrayList newal=new ArrayList();
Iterator i=oldal.iterator();
//在迭代器中迭代中next一次,就要用hasNext()判断一次
while (i.hasNext())
{
Object obj=i.next();
if (!(newal.contains(obj)))//判断是否包含的方法
{
newal.add(obj);
}
}
return newal;
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}</span>
迭代方式的具体实现看下面我的一个实例分析:
<span style="font-size:18px;">/*
迭代方法:就是依次获得集合中的元素,相当于把内容遍历出来!
*/
import java.util.*;
class IteratorDemo
{
public static void main(String[] args)
{
ArrayList ali=new ArrayList();
ali.add("java1");
ali.add("java2");
ali.add("java3");
ali.add("");
Iterator it=ali.iterator();
//上述理解:接口就是指向一个具体的类对象,这里ali.iterator()就是具体的一个类的对象
//只不过是通过自身内部的方法来实现的!
sop(it.hasNext()); //判断还有没有下一个元素
while (it.hasNext()) //当为true时才执行
{
sop(it.next());//有就继续拿出即可
}
//高效率的遍历
for (Iterator it1=ali.iterator(); it1.hasNext(); )
{
sop(it1.next());
}//Iterator it1=ali.iterator()这在for中,用完就自动消失了
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}</span>
对于list【LinkedList】同样看具体的实例分析:
<span style="font-size:18px;">/*
LinkedList:底层数据机构是链表结构,这种结构对于增加和删除效率特别高效!
【原因】因为链表结构,少了对角标的控制,不像控制ArrayList集合那样通过角标去控制,过程较为
繁琐。
【优点】增加,删除数据元素效率高
【缺点】查看,修改数据元素效率稍低
*/
import java.util.*;
/*
LinkedList的特有方法:
addFirst();
addlast();
getFirst();
getLast();
【注意】get方法获取元素,但是不删除元素
removeFirst();
removeLast();
【注意】remove方法即获取元素,又删除元素
如果集合中没有元素,那么会出现NoSuchElementException异常(没有这样元素的异常)
在JDK1.6中出现了替代以上的方法
offerFirst(); //添加
offerLast();
peekFirst(); //获取
peekLast();
pollFirst(); //删除
pollLast();
这三种添加,获取,删除的方法,不会抛出异常,如果没有,就操作失败,返回值为null
*/
class LinkedListDemo
{
public static void main(String[] args)
{
LinkedList ll=new LinkedList();
ll.addLast("java1");
ll.addLast("java2");
ll.addLast("java3");
ll.addLast("java4");
ll.addLast("java5");
ll.addLast("java6");
//sop(ll); //如果添加的时候用addFirst()就倒序打印了!如果用addLast就正序打印
//sop(ll.getFirst()); //获取第一个,
//sop(ll.getLast());//获取最后一个;
//sop(ll.removeFirst()); //获取出了java1
//sop(ll.size());//删除了,变成了5
//用迭代器的方法:
ListIterator li=ll.listIterator();
while (li.hasNext())
{
sop(li.next());
}
//sop(ll.size());
//sop(ll.isEmpty());
//相当于迭代器的方法
while (!ll.isEmpty())
{
sop(ll.removeFirst()); //因为它删除的同时也获取到了,所以这样也能迭代出来
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}</span>
<span style="font-size:18px;"><span style="background-color: rgb(255, 255, 102);"><span style="font-size:32px;"><strong>【更好的实例】来熟悉的运用【LinkedList】</strong></span></span></span>
<span style="font-size:18px;">/*
使用LinkedList链表结构来模拟一个堆栈或者队列的数据结构
堆栈结构:先进后出,如同一个杯子,先放入的最后才能拿出来!
队列结构:先进先出(First in First out,简称:FiFo),如同一跟水管!
思路:就是用LinkedList的特有方法add和remove方式去模拟
具体做法:【数据的存入方式和取出方式的不同】
堆栈模拟:addFirst()先进 removeFirst()后出
队列模式:addFirst()先进 removeLast()先出
*/
import java.util.*;
//自定义堆栈模拟类:
class DuiZhanTest
{
private LinkedList ll;
DuiZhanTest()
{
ll=new LinkedList(); //类对象建立,就创建LinkedList集合:
}
public void addMyDZ(Object obj) //添加对象的方法
{
ll.addFirst(obj);
}
public Object getMyDZ()
//获取对象的方法【注意】这里removeFirst方法特殊:
//可以先获得其元素,再进行删除;
{
return ll.removeFirst();
}
//判断元素是否为空
public boolean isNull()
{
return ll.isEmpty();
}
}
//同理:自定义队列模拟类
class DuiLieTest
{
private LinkedList ll;
DuiLieTest()
{
ll=new LinkedList();
}
public void addMyDL(Object obj)
{
ll.addFirst(obj);
}
public Object getMyDL()
{
return ll.removeLast();
}
public boolean isNull()
{
return ll.isEmpty();
}
}
class LinkedListTest
{
public static void main(String[] args)
{
sop("***********堆栈模拟*************");
DuiZhanTest dzt=new DuiZhanTest();
dzt.addMyDZ("java1");
dzt.addMyDZ("java2");
dzt.addMyDZ("java3");
dzt.addMyDZ("java4");
//简单的判断:元素不为空就取出再删除;
while (!dzt.isNull())
{
sop(dzt.getMyDZ());
}
sop("***********队列模拟*************");
DuiLieTest dlt = new DuiLieTest();
dlt.addMyDL("wangkeze1");
dlt.addMyDL("wangkeze2");
dlt.addMyDL("wangkeze3");
dlt.addMyDL("wangkeze4");
//原理一样,不再细说!
while (!dlt.isNull())
{
sop(dlt.getMyDL());
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}</span>
【Vector】介绍:
<span style="font-size:18px;"><span style="font-size:24px;">/*
Vector的底层数组结构也是“数组”
Vector的结构是线程同步,但是效率比较低,ArrayList是线程不同步的,但是效率很高!
为此,对于多线程的,最好用ArrayList,线程虽然不同步,但是可以自己加锁去完成,因为效率高
对了单线程,就用Vector就行,很安全!
演示
1.0版本中,枚举就是Vector特有的取出方式
*/
import java.util.*;
class VectorDemo
{
public static void main(String[] args)
{
Vector v=new Vector();
v.add("java1");
v.add("java2");
v.add("java3");
v.add("java4");
//这种枚举和Iterator基本相同,都能取出元素,只是Itertor是迭代的方式取出
Enumeration e=v.elements();
while (e.hasMoreElements())
{
sop(e.nextElement());
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
</span></span>
总结:
对于List中对象的有序性,和无重复性,基本上具体的方法和扩展都运用到了,多看api中的接口,方法实现,自然而然就知道怎么用了……
在List下,这三个助手非常重要都是常用的:
ArrayList,LinkedList,Vector他们的区别在于:各自底层是实现方式不一样:
(1)ArrayList:底层数据结构是:数组型(有角标,方便查看、删除的操作(效率很高),但是不宜添加,修改,因为需要控制角标实现,所以会较低一些效率!)
(2)LinkedList:底层数据结构是:链表型 (没有角标,方便增加、删除的操作(效率高),但是不易于查看或者修改等操作)
(3)Vector:底层数据结构也是一个数组型,ArrayList是在Vector的基础上引申出来的。所以两者的用法都大同小异,只是Vector是唯一有枚举方法的实现类!
但是【注意】Vector是线程同步的,而ArrayList不是线程同步!对于开发多线程的项目:最好用ArrayList,因为这样的效率很高,但是必须加锁;而在单线程中,最好用Vector,这样的效率很高!