疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java集合框架之Colletion子接口List


 

   

  一、Collection的子接口

  List:有序(存入和取出的顺序一致),元素都有索引(即角标),元素可以重复。

  Set:元素不能重复,无序的。

  首先讲讲List。

  A、List特有的常见方法(都有一个共性的特点就是可以操作角标)。List接口是可以完成对元素的增删改查,List接口的实现是通过子类来完成:

  现在我们初始化一个List接口:List ll=new ArrayList();

  接下来说说List的主要常用的方法。

  1、添加(通过索引的位置来添加元素)

  [java] 

  void add(index,element);

  void add(index,Collection)

  //List特有的取出方式之一

  for(inti=0;i

  System.out.println(ll.get(i));

  }

  2、删除(删除相应索引位置的元素)

  [java] 

  Object remove(index);//返回被删除的元素

  3、修改(修改指定索引位置的元素,并返回修改前的元素)

  [java] view plain copy print?在CODE上查看代码片派生到我的代码片

  ObjectSet(index,element)//返回被修改的元素

  4、获取:

  [java] view plain copy print?在CODE上查看代码片派生到我的代码片

  Object get (index);

  int IndexOf(object);//返回此列表中第一次出现指定元素的索引,如果此列表不包含该素,则返回-1.

  int lastIndexOf(object);//返回此列表中最后一次出现指定的元素,如果此列表不包含该元素,则返回-1.

  List subList(int from,int to);//包含头,不包含尾,获取子列表。

  测试程序代码如下:

  [java]

  代码如下:

  package com.wq.list;

  /**

  * 添加一个课程类,提供课程的选择

  * @author LULEI

  *

  */

  public class Courses {

  private String id;//课程序号

  private String name;//课名

  public Courses(){

  }

  public Courses(String id,String name){

  this.setId(id);

  this.setName(name);

  }

  public String getId() {

  return id;

  }

  public void setId(String id) {

  this.id = id;

  }

  public String getName() {

  return name;

  }

  public void setName(String name) {

  this.name = name;

  }

  }

  [java] 

  //测试List的一些方法:

  package com.wq.list;

  import java.util.ArrayList;

  import java.util.Arrays;

  import java.util.Iterator;

  import java.util.List;

  public class ListTest {

  //用于存放备选课程的List

  public List courseToSelect;

  public ListTest(){

  this.courseToSelect=new ArrayList();

  }

  //用于courseToSelect添加备选课程

  public void testAdd(){

  //创建一个课程的实例,并通过使用add方法,将该实例

  //添加到备选课程List中

  Courses cr1=new Courses("1", "数据库");

  courseToSelect.add(cr1);//将课程添加到备选课程List中

  Courses temp=(Courses)courseToSelect.get(0);//选取List列表中的第一个元素

  System.out.println("添加了课程:"+temp.getId()+"."+temp.getName());

  Courses cr2=new Courses("2","JAVA");

  courseToSelect.add(0, cr2);

  Courses temp2=(Courses)courseToSelect.get(0);

  System.out.println("添加了课程:"+temp2.getId()+"."+temp2.getName());

  /*

  * 下面代码会出现越界的异常

  Courses cr3= new Courses("4", "test");

  courseToSelect.add(4,cr3);

  //Courses cr3=(Courses)courseToSelect.get(4);

  //System.out.println("添加了课程:"+cr3.getId()+"."+cr3.getName());

  *

  */

  Courses cr7=new Courses("1", "数据库");

  courseToSelect.add(cr7);//将课程添加到备选课程List中

  Courses temp7=(Courses)courseToSelect.get(2);//选取List列表中的第一个元素

  System.out.println("添加了课程:"+temp7.getId()+"."+temp7.getName());

  //addAll()方法的使用

  Courses[] cr3={new Courses("3","高数"),new Courses("4","英语")};

  courseToSelect.addAll(Arrays.asList(cr3));//将数组转换成List集合

  Courses temp3=(Courses)courseToSelect.get(3);

  Courses temp4=(Courses)courseToSelect.get(4);

  System.out.println("添加了两门课:"+temp3.getId()+"."+temp3.getName()

  +temp4.getId()+"."+temp4.getName());

  Courses[] cr4={new Courses("5","高等语文"),new Courses("6","数据处理")};

  courseToSelect.addAll(2,Arrays.asList(cr4)); //将数组转换成List集合

  Courses temp5=(Courses)courseToSelect.get(2);

  Courses temp6=(Courses)courseToSelect.get(3);

  System.out.println("添加了两门课:"+temp5.getId()+"."+temp5.getName()

  +temp6.getId()+"."+temp6.getName());

  }

  /**

  * 创建一个Get方法,用于获取List中的元素的方法

  */

  public void testGet(){

  int num=courseToSelect.size();//获取List的长度

  System.out.println("可以选择的课程如下:");

  for(int i=0;i

  Courses cr=(Courses) courseToSelect.get(i);

  System.out.println(cr.getId()+"."+cr.getName());

  }

  }

  /**

  * 使用迭代器的方法来获取List中的元素

  * @param args

  */

  public void testIterator(){

  //迭代器是个借口,依赖集合存在

  Iterator i=courseToSelect.iterator();

  System.out.println("可以选择的课程如下(通过迭代器实现的):");

  while(i.hasNext()){

  Courses cr=(Courses)i.next();

  System.out.println(cr.getId()+"."+cr.getName());

  }

  }

  /**

  * 使用for each的方法来获取List中的元素

  * @param args

  */

  public void testForEach(){

  System.out.println("可以选择的课程如下(通过foreach实现的):");

  for(Object obj:courseToSelect){

  Courses cr=(Courses)obj;

  System.out.println(cr.getId()+"."+cr.getName());

  }

  }

  /**

  * 通过set()方法来修改List元素

  * @param args

  */

  public void testModify(){

  courseToSelect.set(4, new Courses("7", "毛概"));

  }

  /**

  * 学会使用remove()方法来删除List中的元素

  * 这种方法的参数是obj,还有一种remove方法的参数是索引、

  * 如:remove(4);即可获得同样的效果

  * @param args

  */

  public void testRemove(){

  Courses cr=(Courses) courseToSelect.get(4);

  System.out.println("将要删除的课程是:"+cr.getId()+"."+cr.getName());

  courseToSelect.remove(cr);

  System.out.println("课程已删除");

  testForEach();

  }

  /**

  * 使用removeAll()方法来删除多个List中的对象

  * @param args

  */

  public void testRemoveAll(){

  Courses[] crs={(Courses) courseToSelect.get(4),

  (Courses) courseToSelect.get(5)};

  //removeAll的参数是一个集合,所以要将

  //Courses数组转换成集合List

  courseToSelect.removeAll(Arrays.asList(crs));

  testForEach();

  }

  /**

  * 创建一个奇怪的方法,用来给List添加字符串

  * @param args

  */

  public void testAddString(){

  System.out.println("到底能不能添加字符串呢!!");

  courseToSelect.add("这是一个很无辜的字符串");

  }

  public static void main(String[] args){

  ListTest lt=new ListTest();

  lt.testAdd();

  lt.testGet();

  lt.testIterator();

  lt.testAddString();

  lt.testForEach();

  // lt.testModify();

  // lt.testForEach();

  // lt.testRemove();

  // lt.testRemoveAll();

  }

  }

  注意上面的例子我没有使用Iterator迭代器,而是使用了foreach语句。不过,接下来我们看看一个使用迭代器遍历集合出错的代码:

  主要代码如下:

  [java] view plain copy print?在CODE上查看代码片派生到我的代码片

  ..........

  ll.add(“qwe1”);

  ll.add(“qwe2”);

  ll.add(“qwe3”);

  Iterator it=ll.iterator();//获取List集合的迭代器的对象

  while(it.hasnext()){

  Object obj=it.next();

  if(obj.equals(“qwe2”)){

  ll.add(“abc9”);//在迭代器中给集合添加元素

  }

  else{

  System.out.println(“next:”+obj);//打印元素

  }

  }

  以上就是一段代码,但是在运行while循环中会出现异常:Java.util.concurrentModificationException。主要的原因是:在迭代器过程中,不要直接使用集合来操作元素,容易抛出异常。怎么解决呢???我们可以使用Iterator的子接口ListIterator来完成在迭代器中对元素进行更多的操作。

  更换代码如下:

  [java] view plain copy print?在CODE上查看代码片派生到我的代码片

  ll.add(“qwe1”);

  ll.add(“qwe2”);

  ll.add(“qwe3”);

  ListIterator it=ll.listiterator();//获取List集合的迭代器的对象

  while(it.hasnext()){

  Object obj=it.next();

  if(obj.equals(“qwe2”)){

  it.add(“abc9”);//迭代器对象进行添加元素

  }

  else{

  System.out.println(“next:”+obj);//打印元素

  }

  }

  好,使用ListIterator就可以实现修改集合的操作。我们可以在迭代器中完成增加和删除的操作,修改后的结果会直接映射到集合中的。

  B、List的子类总结

  Vector:内部是数组数据结构,是同步的(即线程安全的)。增删修改查询都很慢。(不常用)

  ArrayList:内部是数组数据结构的,是不同步的。替代了Vector,查询的速度快。

  LinkedList:内部是双向链表的数据结构,是不同步的。增删元素的速度非常快。

  这里我们做一个练习:使用LinkedList来模拟一个堆栈和队列的数据结构。

  堆栈:先进后出(First In Last Out)FILO

  队列:先进先出(First In First Out)FIFO

  我们应该描述这样一个容器,给使用者提供一个容器对象完成这两种结构的一种。LinkedList(可以实现队列和堆栈的功能)常用的方法如下:

  ---添加

  addFirst();

  addLast();//从jdk1.6后改成 offerFirst(),和offerLast();

  ---获取

  getFirst();//获取但不移除,如果链表为空。抛出NoSuchElementException

  getLast();

  从jdk1.6后上面两个改成:

  peekFirst();//获取但不移除,如果链表为空,则返回null

  peekLast();

  ---删除

  removeFirst();//获取,且移除当前的元素。如果链表为空。抛出NoSuchElementException

  removeLast();

  从jdk1.6后上面两个改成:

  poolFirst();//获取且移除当前的元素,如果链表为空,则返回null

  poolLast();

  代码的实现如下:

  [java] view plain copy print?在CODE上查看代码片派生到我的代码片

  ///队列类

  package com.wq.linkedlist;

  import java.util.LinkedList;

  import java.util.List;

  public class DuiLie {

  //这个类是实现队列的功能的

  LinkedList ls=new LinkedList();//内部是链表结构的list

  public DuiLie(){

  }

  public void addElement(Object obj){

  //ls.addLast(obj);//在后面添加元素

  ls.offerLast(obj);//jdk1.6版本后的在后面添加元素方法

  System.out.println(obj+"已经加入队列");

  }

  public void removeElement(){

  Object obj=ls.pollFirst();//jdk1.6版本的删除最前面的元素,取代了removeFirst()方法

  System.out.println(obj+"已经出队列");

  }

  }

  ///堆栈类

  package com.wq.linkedlist;

  import java.util.LinkedList;

  public class DuiZhan {

  //这个类是实现堆栈的功能的

  LinkedList ls=new LinkedList();//内部是链表结构的list

  public DuiZhan(){

  }

  public void addElement(Object obj){

  //ls.addLast(obj);//在后面添加元素

  ls.offerLast(obj);//jdk1.6版本后的在后面添加元素方法

  System.out.println(obj+"已经加入堆栈");

  }

  public void removeElement(){

  Object obj=ls.pollLast();//jdk1.6版本的删除最前面的元素,取代了removeLast()方法

  System.out.println(obj+"已经退出堆栈");

  }

  }

  /////测试上述两个类

  package com.wq.linkedlist;

  public class test {

  public static void main(String[] args) {

  // TODO Auto-generated method stub

  DuiZhan dz=new DuiZhan();//实例化堆栈的对象

  DuiLie dl=new DuiLie();//实例化队列的对象

  //实现堆栈的功能

  System.out.println("实现堆栈的功能");

  dz.addElement(111);

  dz.addElement(222);

  dz.addElement(333);

  dz.addElement(444);

  dz.removeElement();

  dz.removeElement();

  dz.removeElement();

  dz.removeElement();

  System.out.println();

  //实现队列的功能

  System.out.println("实现队列的功能");

  dl.addElement(111);

  dl.addElement(222);

  dl.addElement(333);

  dl.addElement(444);

  dl.removeElement();

  dl.removeElement();

  dl.removeElement();

  dl.removeElement();

  }

  }

  运行结果如下:

  [java] view plain copy print?在CODE上查看代码片派生到我的代码片

  实现堆栈的功能

  111已经加入堆栈

  222已经加入堆栈

  333已经加入堆栈

  444已经加入堆栈

  444已经退出堆栈

  333已经退出堆栈

  222已经退出堆栈

  111已经退出堆栈

  实现队列的功能

  111已经加入队列

  222已经加入队列

  333已经加入队列

  444已经加入队列

  111已经出队列

  222已经出队列

  333已经出队列

  444已经出队列

  C、ArrayList集合存数自定义对象

  1、这里,我要提一下。集合里存储的都是对象的引用(就是对象在堆中的绝对地址的值),迭代器里迭代的也是集合中的对象引用。

  代码如下:

  [java] view plain copy print?在CODE上查看代码片派生到我的代码片

  package com.wq.arraylist;

  import java.util.ArrayList;

  import java.util.Iterator;

  import java.util.List;

  import com.wq.person.Person;

  /**

  * 该类主要完成 去除ArrayList中的重复元素

  * @author LULEI

  *

  */

  public class testArrayList {

  public static void main(String[] args) {

  // TODO Auto-generated method stub

  List li=new ArrayList();

  testDemo1(li);

  }

  public static void testDemo1(List li) {

  //测试传统的对象

  /*

  li.add("111");

  li.add("111");

  li.add("222");

  li.add("333");

  li.add("444");

  li.add("333");

  */

  /*

  * 测试添加自定义的对象Person

  */

  li.add(new Person("wq1",21));

  li.add(new Person("wq2",22));

  li.add(new Person("wq1",21));

  li.add(new Person("wq3",23));

  li.add(new Person("wq2",22));

  li.add(new Person("wq3",23));

  System.out.println(li);

  //调用换取单个元素的方法

  li=getSingelElement(li);

  System.out.println(li);

  }

  public static List getSingelElement(List li) {

  // TODO Auto-generated method stub

  List temp=new ArrayList();//新建一个List

  for(Iterator it=li.iterator();it.hasNext();){

  Object obj=it.next();

  if(!temp.contains(obj)){//如果不包含该元素

  temp.add(obj);//添加到新的List中

  }

  }

  return temp;

  }

  }

  这里就先这样,下一篇将介绍Set接口。