`
bolange
  • 浏览: 27088 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

集合框架——List

    博客分类:
  • Java
阅读更多

      List集合为列表类型,列表的主要特征是存放其中的对象以线性方式存储,没有特定的顺序,只有一个开头和结尾,当然,它与根本没有顺序的集类型时不同的。

1. List集合的用法 
      List集合包括List接口以及List接口的所有实现类。因为List接口继承了Collection接口,所以List接口拥有Collection接口提供的所有常用方法,又因为List是列表类型,所以List接口还提供了一些适合于自身的常用方法,如下表2所示:



      从上表可以看出,List接口提供的适合于自身的常用方法均与索引有关,这是因为List集合为列表类型,以线性方式存储对象,可以通过对象的索引操作对象。

List接口的常用实现类有ArrayList和LinkedList,在使用List集合时,通常情况下声明为List类型,实例化时根据实际情况的需要,实例化为ArrayList或LinkedList,例如:
List<String> l1 = new ArrayList<String>();//利用ArrayList类实例化List集合
List<String> l2 = new LinkedList<String>();//利用LinkedList类实例化List集合


1.1. add(int index,Object obj)方法和set(int index,Object obj)方法的区别 
      在使用List集合时需要注意区分add(int index,Object obj)方法和set(int index,Object obj)方法,前者是向指定的索引位置添加对象,而后者是修改指定的索引位置的对象。
例如:

Java代码 复制代码
  1. import java.util.*;   
  2. public class TestList{   
  3.     public static void main(String args[]){   
  4.         String a = "A" , b = "B" , c =  "C" , d = "D" , e = "E";   
  5.         List<String> list = new LinkedList<String>();   
  6.         list.add(a);   
  7.         list.add(e);   
  8.         list.add(d);   
  9.         list.set(1,b);//将索引位置为1的对象e修改为对象b   
  10.         list.add(2,c);//将对象c添加到索引位置为2的位置   
  11.         Iterator<String> it = list.iterator();   
  12.         while(it.hasNext()){   
  13.             System.out.println(it.next());   
  14.         }   
  15.     }   
  16. }  


程序的运行结果如下:
A
B
C
D
 
      因为List集合可以通过索引位置访问对象,所以还可以通过for循环遍历List集合,例如遍历上面代码中的List集合的代码如下:

Java代码 复制代码
  1. for(int i=0;i<list.size();i++){   
  2.     System.out.println(list.get(i));//利用get(int index)方法获得指定索引位置的对象   
  3. }  

1.2. indexOf(Object obj)方法和lastIndexOf(Object obj)方法的区别 
      在使用List集合时需要注意区分index(Object obj)方法和lastIndexOf(Object obj)方法,前者是获得指定对象的最小的索引位置,而后者是获得指定对象的最大的索引位置。前提条件是指定的对象在List集合中具有重复的对象,如果在List集合中有且仅有一个指定的对象,则通过这两个方法获得的索引位置是相同的。
例如:

Java代码 复制代码
  1. String a = "A" , b = "B" , c = "C" , d = "D" , repeat = "Repeat";   
  2. List<String> list = new ArrayList<String>();   
  3. list.add(a);      //索引位置为0   
  4. list.add(repeat); //索引位置为1   
  5. list.add(b);      //索引位置为2   
  6. list.add(repeat); //索引位置为3   
  7. list.add(c);      //索引位置为4   
  8. list.add(repeat); //索引位置为5   
  9. list.add(d);      //索引位置为6   
  10. System.out.println(list.indexOf(repeat));   
  11. System.out.println(list.lastIndexOf(repeat));   
  12. System.out.println(list.indexOf(b));   
  13. System.out.println(list.lastIndexOf(b));  

程序的运行结果如下:
1
5
2
2

 

 

 

1.3. subList(int fromIndex,int toIndex)方法 
      在使用subList(int fromIndex,int toIndex)方法截取现有List集合中的部分对象生成新的List集合时,需要注意的是,新生成的集合中包含起始索引位置代表的对象,但是不包含终止索引位置代表的对象。
例如:

Java代码 复制代码
  1. String a = "A" , b = "B" , c = "C" , d = "D" , e = "E";   
  2. List<String> list = new ArrayList<String>();   
  3. list.add(a);   
  4. list.add(b);   
  5. list.add(c);   
  6. list.add(d);   
  7. list.add(e);   
  8. list = list.subList(1,3);   
  9. for(int i=0;i<list.size();i++){   
  10.     System.out.println(list.get(i));   
  11. }  

程序的运行结果如下:
B
C


2. 使用ArrayList类 
      ArrayList类实现了List接口,由ArrayList类实现的List集合采用数组结构保存对象。数组结构的优点是便于对集合进行快速的随机访问,如果经常需要根据索引位置访问集合中的对象,使用由ArrayList类实现的List集合的效率较好。数组结构的缺点是向指定索引位置插入对象和删除指定索引位置对象的的速度较慢,如果经常需要向List集合的指定索引位置插入对象,或者是删除List集合的指定索引位置的对象,使用由ArrayList类实现的List集合的效率则较低,并且插入或删除对象的索引位置越小效率越低,原因是当向指定的索引位置插入对象时,会同时将指定索引位置及之后的所有对象相应的向后移动一位,如图2所示。当删除指定索引位置的对象时,会同时将指定索引位置之后的所有对象相应的向前移动一位,如图3所示。如果在指定的索引位置之后有大量的对象,将严重影响对集合操作效率。





下面看一个模仿经常需要随机访问集合中对象的例子:
例如:

Java代码 复制代码
  1. String a = "A" , b = "B" , c = "C" , d = "D" , e = "E";   
  2. List<String> list = new ArrayList<String>();   
  3. list.add(a);   
  4. list.add(b);   
  5. list.add(c);   
  6. list.add(d);   
  7. list.add(e);   
  8. System.out.println(list.get((int)(Math.random()*5)));  

程序运行结果是随机的。

3. 使用LinkedList类 
      LinkedList类实现了List接口,用LinkedList类实现的List集合采用链表结构保存对象。链表结构的优点是便于向集合中插入和删除对象,如果经常需要向集合中插入对象,或者是从集合中删除对象,使用由LinkedList类实现的List集合的效率较好。链表结构的缺点是随机访问对象的速度较慢,如果经常需要随机访问集合中的对象,使用LinkedList类实现的List集合的效率较低。用LinkedList类实现的List集合便于插入或删除对象的原因是当插入或删除对象时,只需要简单的修改链接位置,分别如图4和图5所示,省去了移动对象的操作。





      LinkedList类还根据采用链表结构保留对象的特点,提供了几个专有的操作集合的方法,如下表3所示:



例如:

Java代码 复制代码
  1. String a = "A" , b = "B" , c = "C" , test = "Test";   
  2. LinkedList<String> list = new LinkedList<String>();   
  3. list.add(a);//索引位置为0   
  4. list.add(b);//索引位置为1   
  5. list.add(c);//索引位置为2   
  6. System.out.println(list.getFirst());//获得并输出链表开头的对象   
  7. list.addFirst(test);//向链表的开头添加一个对象   
  8. System.out.println(list.getFirst());//获得并输出链表开头的对象   
  9. list.removeFirst();//移除链表开头的对象   
  10. System.out.println(list.getFirst());//获得并输出链表开头的对象  

程序的运行结果如下:
A
Test
A


4. 客户化排序List集合 
      在使用List集合时,通常情况下希望从集合中得到的对象是按照一定顺序排列的,但是List集合的默认排序方式为按照对象的插入顺序,可以通过java.util.Collections类的静态方法sort(List<T> list)、sort(List<T> list,Comparator<? super T> c)或reverse(List<?> list)对集合中的对象进行客户化排序,其中方法sort(List<T> list)和reverse(List<?> list)要求集合中的对象必须实现java.lang.Comparable接口,即实现方法compareTo(),该方法的具体定义如下:
public int compareTo(T o);
方法sort(List<T> list)是将集合中的所有对象按正序排列,方法reverse(List<?> list)是将集合中的所有对象按倒序排列;方法sort(List<T> list,Comparator<? super T> c)不要求集合中的对象必须实现Comparable接口,但是在使用该方法时需要显式设置比较器,即该方法的第2个入口参数,比较器必须实现java.util.Comparator接口,即实现方法compare(),该方法的就具体定义如下:
int compare(T o1,T o2);
比较器的功能是实现对集合中所有对象的排序策略。
注意:List集合进行客户化排序的前提条件是List集合中的元素为同一类型。

1.1. 通过实现java.lang.Comparable接口实现客户化排序
例如:
源文件:CnToSpell.java(源文件见下载处CnToSpell.rar压缩文件)
源文件:Person.java

Java代码 复制代码
  1. public class Person implements Comparable{   
  2.     private String name;   
  3.     private long id_card;   
  4.     public String getName(){   
  5.         return name;   
  6.     }   
  7.     public void setName(String name){   
  8.         this.name = name;   
  9.     }   
  10.     public long getId_card(){   
  11.         return id_card;   
  12.     }   
  13.     public void setId_card(long id_card){   
  14.         this.id_card = id_card;   
  15.     }   
  16.     public int compareTo(Object o){//实现Comparable接口的方法   
  17.         Person p = (Person)o;   
  18.         String s1 = CnToSpell.getFullSpell(this.name);//获得汉字的全拼   
  19.         String s2 = CnToSpell.getFullSpell(p.getName());   
  20.         return s1.compareTo(s2);//比较两个字符串的大小   
  21.     }   
  22. }  

源文件:TestList.java

Java代码 复制代码
  1. import java.util.*;   
  2. public class TestList{   
  3.     public static void main(String args[]){   
  4.         List<Person> list = new ArrayList<Person>();   
  5.         String names[] = {"马先生","王小姐","李先生"};   
  6.         long id_cards[] ={22015,22020,22018};   
  7.         for(int i=0;i<names.length;i++){//初始化List集合   
  8.             Person person = new Person();   
  9.             person.setName(names[i]);   
  10.             person.setId_card(id_cards[i]);   
  11.             list.add(person);   
  12.         }   
  13.         System.out.println("排序前:");   
  14.         for(int i=0;i<list.size();i++){//遍历List集合   
  15.             Person person = list.get(i);   
  16.             System.out.println("-----"+person.getName()+"   "+person.getId_card());   
  17.         }   
  18.         //利用java.util.Collections类的sort(List list)或reverse(List list)方法对List集合排序   
  19.         Collections.sort(list);//按升序排序   
  20.         System.out.println("升序排列后:");   
  21.         for(int i=0;i<list.size();i++){//遍历List集合   
  22.             Person person = list.get(i);   
  23.             System.out.println("-----"+person.getName()+"   "+person.getId_card());   
  24.         }   
  25.         Collections.reverse(list);//按降序排列   
  26.         System.out.println("降序排列后:");   
  27.         for(int i=0;i<list.size();i++){//遍历List集合   
  28.             Person person = list.get(i);   
  29.             System.out.println("-----"+person.getName()+"   "+person.getId_card());   
  30.         }   
  31.     }   
  32. }  

程序的运行结果如下:
排序前:
-----马先生     22015
-----王小姐     22020
-----李先生     22018
升序排列后:
-----李先生     22018
-----马先生     22015
-----王小姐     22020
降序排列后:
-----王小姐     22020
-----马先生     22015
-----李先生     22018

利用这种方式实现对List集合进行客户化排序,缺点是对于每个类只能采用一种排序方式,对于排序方式需求单一的对象,可采用该种方式。


1.2. 通过实现java.util.Comparator接口实现客户化排序
例如:
源文件:CnToSpell.java(源文件见下载处CnToSpell.rar压缩文件)
源文件:Person.java

Java代码 复制代码
  1. public class Person{   
  2.     private String name;   
  3.     private long id_card;   
  4.     public long getId_card(){   
  5.         return id_card;   
  6.     }   
  7.     public void setId_card(long id_card){   
  8.         this.id_card = id_card;   
  9.     }   
  10.     public String getName(){   
  11.         return name;   
  12.     }   
  13.     public void setName(String name){   
  14.         this.name = name;   
  15.     }   
  16. }  

源文件:PersonComparator.java

Java代码 复制代码
  1. import java.util.Comparator;   
  2. public class PersonComparator implements Comparator{   
  3.     //为可能参与排序的属性定义同名的静态常量值   
  4.     public static final int NAME = 1;   
  5.     public static final int ID_CARD = 2;   
  6.     private int orderByColumn = 1;//默认排序为按姓名排序   
  7.     public int compare(Object o1,Object o2){//实现Comparator接口的方法   
  8.         Person p1 = (Person)o1;   
  9.         Person p2 = (Person)o2;   
  10.         int result = 0;//默认的判断结果为两个对象相等   
  11.         switch(orderByColumn){//判断排序条件   
  12.             case 1://按姓名排序   
  13.                 String s1 = CnToSpell.getFullSpell(p1.getName());//获得汉字的全拼   
  14.                 String s2 = CnToSpell.getFullSpell(p2.getName());   
  15.                 result = s1.compareTo(s2);//比较两个字符串的大小   
  16.                 break;   
  17.             case 2:   
  18.                 result = (int)(p1.getId_card()-p2.getId_card());//比较两个整数的大小   
  19.                 break;   
  20.         }   
  21.         return result;   
  22.     }   
  23.     public void orderByColumn(int orderByColumn){//用来设置排序条件   
  24.         this.orderByColumn = orderByColumn;   
  25.     }   
  26. }  

源文件:TestList.java

Java代码 复制代码
  1. public class TestList{   
  2.     public static void main(String args[]){   
  3.         List<Person> list = new ArrayList<Person>();   
  4.         String names[] ={"马先生","王小姐","李先生"};   
  5.         long id_cards[] = {22015,22020,22018};   
  6.         for(int i= 0;i<names.length;i++){   
  7.             Person person = new Person();   
  8.             person.setName(names[i]);   
  9.             person.setId_card(id_cards[i]);   
  10.             list.add(person);   
  11.         }   
  12.         System.out.println("排序前:");   
  13.         for(int i=0;i<list.size();i++){   
  14.             Person person = list.get(i);   
  15.             System.out.println("-----"+person.getName()+"   "+person.getId_card());   
  16.         }   
  17.         PersonComparator personComparator = new PersonComparator();//创建比较器对象   
  18.         System.out.println("按姓名排序:");   
  19.         Collections.sort(list,personComparator);//默认为按姓名排序,排序List集合   
  20.         for(int i=0;i<list.size();i++){   
  21.             Person person = list.get(i);   
  22.             System.out.println("-----"+person.getName()+"   "+person.getId_card());   
  23.         }   
  24.         System.out.println("按编号排序:");   
  25.         personComparator.orderByColumn(PersonComparator.ID_CARD);//设置为按编号排序   
  26.         Collections.sort(list,personComparator);   
  27.         for(int i=0;i<list.size();i++){   
  28.             Person person = list.get(i);   
  29.             System.out.println("-----"+person.getId_card()+"    "+ person.getName());   
  30.         }   
  31.     }   
  32. }  

程序的运行结果如下:
排序前:
-----马先生     22015
-----王小姐     22020
-----李先生     22018
按姓名排序:
-----李先生     22018
-----马先生     22015
-----王小姐     22020
按编号排序:
-----22015      马先生
-----22018      李先生
-----22020      王小姐

利用这种方式实现对List集合进行客户化排序,排除了每个类只能采用一种排序方式的弊端,可以根据实际需要,将List集合按照不同的方式排序。这里是按姓名的全称升序排列,如果想改为降序排列,只需将例子中的的如下代码:

Java代码 复制代码
  1. result = s1.compareTo(s2);  


修改改为:

Java代码 复制代码
  1. result = s2.compareTo(s2);  

编号也是按升序排列的,如果也想改为降序排列,只需将例子中的如下代码:

Java代码 复制代码
  1. result = (int)(p1.getId_card()-p2.getId_card());  


修改为:

Java代码 复制代码
  1. result = (int)(p2.getId_card()-p1.getId_card());  

 

分享到:
评论

相关推荐

    Java全能学习面试手册——Java面试题库.zip

    Java全能学习面试手册——Java面试题库.zip 01 7道消息队列ActiveMQ面试题...86 集合框架.pdf 87 精选7道Elastic Search面试题!.pdf 88 精选8道Dubbo面试题!.pdf 89 精选17道海量数量处理面试题!.pdf 90 看透Spring

    基于SpringBoot+Layui+shiro安全框架和Ehcache缓存框架搭建的学生管理系统源码+项目说明.zip

    新接触的Layui的表单可以说是非常实用了,但是我用ehcache缓存对list集合进行缓存时,layui的表格分页功能就会失效(比如我查询学生列表,并且对这个list添加了缓存,那么在前端展示时,layui的分页功能就会失效,转...

    JAVA学习笔记第十四天

    JAVA学习笔记第十四天——字符集编码解码、泛型的使用、数据结构栈和链表、集合框架&List,示例代码,里面主要是知识点的具体使用和各种现象。

    基于SpringBoot+Layui搭建的学生管理系统源码+项目说明(毕设).zip

    新接触的Layui的表单可以说是非常实用了,但是我用ehcache缓存对list集合进行缓存时,layui的表格分页功能就会失效(比如我查询学生列表,并且对这个list添加了缓存,那么在前端展示时,layui的分页功能就会失效,转...

    重构——改善既有代码的设计

     The JUnit Testing Framework Junit测试框架   Adding More Tests 添加更多测试  Chapter 5:Toward a Catalog of Refactorings 重构目录   Format of the Refactorings 重构描述的格式   Finding ...

    Java面试题资料,包含核心知识,消息队列,大数据等

    这份资料不仅应该触及Java的基石——例如JVM的工作原理、内存模型、垃圾回收机制,以及Java的集合框架中的核心接口与实现类,如List、Set、Map等,更应对Java的异常处理机制有深入的剖析 此外,考虑到Java技术的...

    实验项目D、Java应用专题编程

    4、初步了解和掌握Java集合框架。 5、掌握Java包装类的基本用法。 6、初步掌握几个常用类和接口的含义和使用。 ★专题:文件IO和数据库编程★ 1、掌握File类的使用。 2、掌握字节流IO的操作。 3、掌握字符流IO的...

    Java 语言基础 —— 非常符合中国人习惯的Java基础教程手册

    了整个 OOP 的框架。这三个概念是:封装、继承性和多态性。除此以外,还需了解对象、 类、消息、接口、及抽象等概念。 2.2.1 对象 现实世界中的对象具两个特征:状态和行为。例如:自行车有状态(传动装置、...

    empty-node-server:用于启动新节点服务器项目的骨架

    这不是一个真正的项目,只是一个文件和配置的集合,旨在作为启动新 Node 服务器项目... 它不包含基于 Node 的 Web 框架——太多可能的选择取决于您开始的项目类型。 但它确实包含我目前最喜欢的测试框架位和测试种子。

    android群雄传

    7.1 Android View动画框架 163 7.1.1 透明度动画 163 7.1.2 旋转动画 163 7.1.3 位移动画 164 7.1.4 缩放动画 164 7.1.5 动画集合 164 7.2 Android属性动画分析 165 7.2.1 ObjectAnimator 166 7.2.2 ...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    7.2.4 参数列表(Parameter List) 159 7.2.5 方法体(Method Body) 160 7.2.6 方法串串烧 160 7.3 方法的参数:让汽车加速 161 7.3.1 方法的参数:让汽车可以加速 161 7.3.2 带参数的方法有何不同? 162 ...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    7.2.4 参数列表(Parameter List) 159 7.2.5 方法体(Method Body) 160 7.2.6 方法串串烧 160 7.3 方法的参数:让汽车加速 161 7.3.1 方法的参数:让汽车可以加速 161 7.3.2 带参数的方法有何不同? 162 ...

    javaSE代码实例

    第14章 集合框架——强大的对象管理器 270 14.1 Object类——所有类的超类 270 14.1.1 toString方法的重写 270 14.1.2 equals方法的意义 271 14.1.3 hashCode方法的意义 272 14.2 重写equals与hashCode...

    asp.net知识库

    如何判断ArrayList,Hashtable,SortedList 这类对象是否相等 帮助解决网页和JS文件中的中文编码问题的小工具 慎用const关键字 装箱,拆箱以及反射 动态调用对象的属性和方法——性能和灵活性兼备的方法 消除由try/...

    dangdang和smartstruts2.rar

    通用电子商务购物平台 --------目的----------- 1.将前期学习技术熟练应用 2.了解项目开发流程,培养开发能力...完善过程注意框架对应的集合和id。 &lt;s:iterator value="list" var="l"&gt;对应与action里的getLIst方法。

    Java Web编程宝典-十年典藏版.pdf.part2(共2个)

    9.2.6 访问List、Set、M印集合 9.2.7 投影与选择 9.3 Struts2的标签库 9.3.1 数据标签的应用 9.3.2 控制标签的应用 9.3.3 表单标签的应用 …… 第10章 邂逅数据库持久化利器 第11章 探秘数据库持久化利器 第12章 ...

    Java开发技术大全 电子版

    14.12.2监听ListSelectionEvent事件556 14.12.3按钮响应事件556 14.12.4对话框的显示557 14.12.5返回用户选择的字体557 14.12.6如何使用字体选择对话框557 14.13GUI程序设计实例4——记事本558 14.13.1增加弹...

    Java JDK实例宝典

    8 对List排序 4. 9 HashSet. LinkedHashSet和TreeSet 4. 10 列表. 集合与数组的互相转换 4. 11 HashMap. Hashtable. LinkedHashMap和TreeMap 4. 12 对Map排序 4. 13 Properties属性文件 第...

    MFC的程序框架剖析

    类的集合,是一套面向对象的函数库,以类的方式提供给用户使用 2、MFC AppWizard是一个辅助我们生成源代码的向导工具,它可以帮助我们自动生成基于MFC框架的源代码 二、基于MFC的程序框架剖析 1、MFC程序的ClassView...

Global site tag (gtag.js) - Google Analytics