黑马程序员 Java基础_4 java集合框架

来源:互联网 发布:python输入输出函数 编辑:程序博客网 时间:2024/03/29 16:15

一、什么是集合框架

在Java API中专门设计了一组类,这组类的功能是实现各种方式的数据存储,这样一组专门用来存储其他对象的类,就称为对象容器类,这组类和接口的设计结构也被统称为集合框架。

下面一张图可以清晰的说明这组类的关系。

Java框架图

从上图可以看出,容器类分两个阵营,Collection为元素集合,而Map为映射关系集合。

我们先总结Collection接口阵营的类。

1、Collection接口

毕老师说过,容器类的方法就四种,增删查改

所以Collection里共性的方法有:

1)add(Object obj)往里面增加元素

       addAll(Collection ct)   往里面增加集合ct的全部元素

2)remove(Object obj)删除obj元素

removeAll(Collection ct)删除集合ct所以元素

clear()  清空集合里所以元素

3)boolean contains(e) 判断结合是否包含e元素

这里还有一个很特殊的方法,因为Collection没有提供获取元素的方法,它只提供了一个迭代器,来迭代返回元素。

iterator()方法返回一个Iterator对象,来对容器进行迭代。

迭代器里面有的方法

hasNext() 判断游标右边是否有元素

next()  返回游标右边的元素并将游标移动到下个位置

remove()删除游标左边的元素

Collection接口又分为List接口和Set接口。

二、List接口

LIst接口有3个常见的实现类。分别是ArrayList,LinkList,Vector。


ArrayList:底层的数据结构时数组结构
      特点:查询速度很快,因为有
角标,但增删速度稍慢线程不同步
LinkedList:底层使用的是链表数据结构
      特点:增删速度很快,但查询速度稍慢,因为每一个元素都链接到前一元素。
Vector:底层是数组结构
      特点:增删查询都很慢,被ArrayList替代了,线程是同步的。

由于ArrayList是最常用的,它跟数组差不多,而且有角标,所以它有很多自己独有的增删查改的方法。

1)add(int index,e)   在指定位置增加给定的元素
               addAll(int index,Collection)  在指定位置增加给定集合中的所有元素,若省略位置参数,则在当前集合的后面依次添加元素

2)remove(int index)     删除集合中指定位置上的元素

3)get(int index)      获取指定位置上的元素
               indexOf(e)    通过指定元素获取其在集合中的位置

4)set(int index,e)把index角标的元素替换成e

这里需要提一点就是List他有自己的迭代且ListIterator。是Iterator的子接口。

下面是一个毕老师的关于ArrayList的代码示例。

class ListDemo   {      public static void sop(Object obj)      {          System.out.println(obj);      }            public static void main(String[] args)       {          methodAdd();          //methodListIterator();      }        public static void methodAdd()      {          //创建一个集合容器,使用Collection接口的子类,ArrayList          ArrayList list = new ArrayList();          //1.添加元素--->add(Object obj),多态           list.add("java01");          list.add("java02");          list.add("java03");          list.add("java04");            ArrayList list2 = new ArrayList();          //1.添加元素--->add(Object obj),多态           list2.add("java05");          list2.add("java06");          list2.add("java07");          list2.add("java08");            //打印原集合          sop("原集合:" + list);          sop("------------------");            //1.在某一个位置上添加元素:add(int index,"新元素")          list.add(1,"java001");          sop("增加后的集合:" + list);          sop("---------");          list.addAll(1,list2);          sop("在list中1位置后添加list2:" + list);          sop("------------------");            //2.删除指定位置上的元素:          list.remove(2);          sop("删除后的集合:" + list);          sop("------------------");            //3.改变某一位置上的元素:set(int index,"要改成的元素")          list.set(2,"java007");          sop("改变角标为2的元素后的元素:" + list);          sop("------------------");            //4.获取元素:get()          list.get(1);          sop("获取角标为1上的元素:" + list.get(1));          sop("------------------");            //通过某个元素获取其在集合中的位置--indexOf("查找的元素")          int m = list.indexOf("java007");          sop("获取“java007”所在的位置:" + m);            //获取从某个位置到另一位置上的元素subList()          List l = list.subList(1,3);          sop("获取从位置1到3上的元素:" + l);          sop("------------------");            //4.获取全部元素          //get方法的for循环          sop("get方法:");          for (int i=0;i<list.size();i++)          {              sop("list(" + i + ")" + list.get(i));          }          sop("------------------");            //迭代器方法:Iterator()          for (Iterator it = list.iterator();it.hasNext(); )          {              sop("next:" + it.next());          }          sop("------------------");  }        public static void methodListIterator()      {          //演示列表迭代器:          ArrayList list = new ArrayList();          //1.添加元素--->add(Object obj),多态           list.add("java01");          list.add("java02");          list.add("java03");          list.add("java04");            //打印原集合          sop("原集合:" + list);          sop("------------------");                        //在迭代过程中,准备添加或删除元素          for (ListIterator it = list.listIterator();it.hasNext(); )          {              Object obj = it.next();              if (obj.equals("java01"))                  it.remove();              else if(obj.equals("java02"))                  it.add("增加java200");              else if(obj.equals("java03"))                  it.set("修改为java300");              sop("obj:" + obj);          }          sop("list :" + list);      }  }

LinkList和Vector用的频率不高,Vector更是被ArrayList所替代,这里就不过多介绍了。

三、Set接口

Set接口跟List接口最大的不同就是Set没有角标,而且元素不可以重复。有三个实现类,HashSet、LinkSet、TreeSet

1、HashSet类

底层数据结构时哈希表,且元素取出方式只有迭代器方法

因为Set接口里面元素都不一样的,所以需要提供怎么才算重复的方法,里面提供了hashCode()和equals()方法来判断是否唯一的标准。

而且,HashSet里面的元素加入顺序和迭代顺序是不一样的,这也验证HashSet里面的元素是无序的。HashSet就先不实例了,下面就介绍TreeSet,基本掌握了TreeSet就掌握HashSet.。

2、HashSet和TreeSet

TreeSet和HashSet差不多,只不过TreeSet里多了一个比较方法来进行排序。而比较方式有两种,要么存进来的元素实现了Comparable接口,要么在创建TreeSet是加入一个Comparator比较器。如果两种方式都实现了,优先考虑比较器来进行比较。


下面一个一个例子

public class TheStudent implements Comparable {private String name;private int math;private int cn;private int es;private int sum;TheStudent(String name,int math,int cn,int es){this.name=name;this.math=math;this.cn=cn;this.es=es;sum=math+cn+es;}public String toString(){return "Student:["+name+","+math+","+cn+","+es+","+sum+"]";}public int hashCode(){return this.name.hashCode()+5*sum;}public boolean equals(Object obj){if(!(obj instanceof TheStudent))throw new RuntimeException("类型不对");TheStudent stu=(TheStudent)obj;return this.name.equals(stu.name)&&this.sum==stu.sum;}public int compareTo(Object stu){TheStudent a=(TheStudent)stu;if(a.sum>this.sum)return 1;else if(this.sum==a.sum)return this.name.compareTo(a.name);return -1;}}

import java.io.*;import java.util.*;class FileStudent {public static Set<TheStudent> inputStudents(){System.out.println("请输入学生信息:");BufferedReader in=new BufferedReader(new InputStreamReader(System.in));String s=null;Set stus=new TreeSet();try{while((s=in.readLine())!=null){if(s.equalsIgnoreCase("exit")) {System.out.println("安全退出。");break;}String[] qiege=s.split(",");stus.add(new TheStudent(qiege[0],Integer.parseInt(qiege[1]),Integer.parseInt(qiege[2]),Integer.parseInt(qiege[3])));}return stus;}catch(Exception e){throw new RuntimeException("输入出错");}finally{try{if(in!=null)in.close();}catch(Exception e){throw new RuntimeException(" 关闭不了");}}}public static void writeto(Set<TheStudent> e){BufferedWriter bfw=null;try{bfw=new BufferedWriter(new FileWriter("student.txt"));for(TheStudent s:e){bfw.write(s.toString()+"\t");bfw.newLine();bfw.flush();}}catch(Exception a){System.out.println("error!");}finally{if(bfw!=null)try{bfw.close();}catch(Exception b){}}}}

 这是一个比较综合的例子,里面有TreeSet的用法。

 关于Map接口,这里就不过多介绍了,基本用法跟Set差不多,因为它里面的键就是用Set来存放的。只要保证键的唯一性就可以了,可以举一反三。


0 0
原创粉丝点击