Java OOP之容器篇

来源:互联网 发布:基督教歌曲下载软件 编辑:程序博客网 时间:2024/06/06 02:01
Java OOP之容器篇

  容器是Java语言中重要的一个环节,用来管理一个对象序列。序列的意思,就是类似于数组,是多个对象按照一定顺序组成的。容器有很多不同于数组的地方,简单的对比一下:
  1、数组的大小是固定的(new的时候确定,或者静态初始化时,由初始值的个数确定),容器的大小是不固定的,会随时增长。
  2、数组的成员有对象,也有基本数据类型的变量,容器的成员只能是对象。(如果存放int之类的变量,会自动转换成对应的包装类Integer的对象,这叫自动装箱。)

  Java语言里面的容器,基本是指java.util包里面,Set接口及其实现类、List接口及其实现类、Map接口及其实现类这些接口和类。常见的容器类是:Set和HashSet类、List接口和ArrayList类、Map接口和HashMap类。学习容器,主要是要学会该容器的特点和如下操作:
  1、创建容器
  2、判断是否为空
  3、计算容器大小
  4、添加元素
  5、取其中的元素
  6、删除元素
  7、查找
  8、遍历
  注意,不见得所有的容器都有如上8条操作,比如Set就没有5。

  那就先说说Set好了。
  在Java语言里面,Set代表一类“无序”容器。所谓无序,并非是指内容杂乱无章,全无顺序。恰好相反,Set类的具体实现,比如HashSet,内部反而是按照一定顺序规则排放的。所谓无序,是指顺序不能被开发者掌握。比如容器中已经有10个元素的时候,继续向其中添加一个元素,谁都不知道这一个究竟是放在哪里,是第一个,还是第二个,还是最后一个?不知道。Set容器内部,逻辑上并没有前后顺序,所有元素都是平等的。

  一、创建Set容器
    Set set = new HashSet();
    Set<Integer> set = new HashSet<Integer>();
  
  前者是传统容器的语法,后者是泛型容器的语法。所谓的泛型容器,就是指内部成员元素的数据类型已经被指定的容器。
    前者创建了一个Set接口的对象,这个对象实际上是HashSet类的实例,HashSet是Set接口的实现类。绝大多数情况下,使用HashSet已经足够了。
    后者创建了一个Set接口的对象,这个对象里面每一个成员元素,都是Integer类型。其他都和前面一样。注意,后一种写法叫做泛型语法。如果没用泛型语法,如前者,容器内的每个成员元素都是Object类型。

  二、判断容器是否为空
    boolean isEmpty = set.isEmpty();
    这是判断容器是否为空,返回值是boolean类型,如果是true就表示容器是空的(没有成员元素),否则表示不为空(即已有至少一个成员元素)。 

  三、计算容器大小
    int size = set.size(); 
    这是返回容器的大小,即容器内成员元素的个数,返回值是整数类型。

  四、添加元素
    boolean success = set.add(obj);
    这是向Set容器中添加元素,有以下几点值得注意:
    1、添加的元素类型:如果是泛型容器,这个参数obj必须是指定的类型(或其子类,这个类型在创建容器时指定);如果不是,那么这个obj只要是Object类(或其子类)就行。
    2、返回值是boolean类型,表示此次添加操作是否成功。
    3、什么情况会添加失败呢?如果容器中已经有这个对象的时候,add操作就会失败。注意,add失败的时候,容器内什么都不变。
    4、添加的元素到了第几个,没办法知道。

  五、取其中的元素
    Set容器没有这个功能,它只能判断某个元素是否在容器中,语法是:
    boolean isInner = set.contains(obj);
    对参数的要求类比add,返回boolean类型,表示容器中是否已经有obj的存在。对于Set容器来说,这基本是唯一的业务操作了。

  六、删除元素
    boolean success = set.remove(obj);
    从Set容器中删掉obj对象,操作成功返回true。什么情况会不成功呢?容器中没有obj这个对象。

  七、查找
    Set容器唯一的查找操作就是contains,参看五。

  八、遍历
    最好的写法是用forEach语法:
    for (Integer a : set){ // 注:Integer是指创建泛型容器时指定的数据类型
    }
    注意:
    1、最好是泛型容器,这种语法还能省掉数据类型转换的麻烦。否则Integer就要换成Object,还是要做数据类型转换。
    2、Set容器内的顺序不可知,所以for循环时,每次a的值究竟是哪个对象,也不可知。只是可以确认,容器中每个对象都会被轮到一次。

 
 Java语言的容器类中,最像数组的就是List了。这里说的List,是指在java.util包中,List接口及其派生类。List接口有三个派生类最常见,分别是ArrayList、LinkedList和Vector,其中用得最多的是ArrayList。在Java语言的设定中,List是以“有序”容器的面目出现的,所谓的有序,不是说内部成员有排序,恰好相反,List默认是不排序的。所谓的有序,是指其中的成员元素的顺序是可以通过代码指定的。
  让我们还是以容器的常用功能的角度来看看List吧。
  一、创建List容器
    List list = new ArrayList();
  
  List<Integer> list = new ArrayList<Integer>();
    前者是传统语法,后者是泛型容器的语法。所谓泛型容器,即指定了容器内成员元素的数据类型的容器。 
    前者创建了List接口的对象,实际上是ArrayList类的实例。
    后者创建了List接口的对象,该对象的所有内部成员元素都是Integer类型的。(与之相比较的是前者的所有成员元素都是Object类型的。)

  二、判断是否为空
    list.isEmpty();
    这是判断容器是否为空,返回值是boolean类型,如果是true就表示容器是空的(没有成员元素),否则表示不为空(即已有至少一个成员元素)。 

  三、计算容器大小
    int size = list.size(); 
    这是返回容器的大小,即容器内成员元素的个数,返回值是整数类型。

  四、添加元素
    boolean success = list.add(obj);
    list.add(2, obj);
    这是向List容器中添加元素,有以下几点值得注意:
    1、添加的元素类型:如果是泛型容器,这个参数obj必须是指定的类型(或其子类,这个类型在创建容器时指定);如果不是,那么这个obj只要是Object类(或其子类)就行。
    2、前者返回值是boolean类型,表示此次添加操作是否成功,后者没有返回值。
    3、前者把新元素添加到List末尾,后者把新元素添加到指定的位置(下标,从0算起),该位置及其之后的元素都向后移动。
    
  五、取其中的元素
    list.get(2);
    输入参数是下标,即第几个元素,从0算起。至于返回值,要看List容器是否泛型,如果是泛型容器,那就返回指定类型的对象,否则返回的是Object类型的对象。

  六、删除元素
    list.remove(2);
    boolean success = list.remove(obj);
  
  前者从List容器中删掉指定下标位置的成员元素,返回值类似五。 
    后者从List容器中删掉obj对象,操作成功返回true。什么情况会不成功呢?容器中没有obj这个对象。

  七、查找
    list.contains(obj);
    list.indexOf(obj);
    前者只看容器中是否存在obj这个对象,有的话返回true,否则返回false。
    后者查找容器中是否存在obj这个对象,有的话返回其下标(整数),否则返回-1。 
 

  八、遍历
    最好的写法是用forEach语法:
    for (Integer a : list){ // 注:Integer是指创建泛型容器时指定的数据类型
    }
    注意:
    1、最好是泛型容器,这种语法还能省掉数据类型转换的麻烦。否则Integer就要换成Object,还是要做数据类型转换。
    2、List容器内的顺序是固定的,所以for循环时,可以看到a是按照list容器的顺序依次遍历的。
    3、这种遍历有一个缺点,就是没有下标,所以需要下标这个值的时候,还是用传统循环遍历好了,遍历语法是:
    for (int i=0; i<list.size(); i++) 
 {
      Integer a = list.get(i);
  
    …… 
    } 
    这样a仍然是遍历时每个成员元素的引用,但是多了一个i是对应的下标。
 Java语言的容器类中,最像数组的就是List了。这里说的List,是指在java.util包中,List接口及其派生类。List接口有三个派生类最常见,分别是ArrayList、LinkedList和Vector,其中用得最多的是ArrayList。在Java语言的设定中,List是以“有序”容器的面目出现的,所谓的有序,不是说内部成员有排序,恰好相反,List默认是不排序的。所谓的有序,是指其中的成员元素的顺序是可以通过代码指定的。
  让我们还是以容器的常用功能的角度来看看List吧。
  一、创建List容器
    List list = new ArrayList();
  
  List<Integer> list = new ArrayList<Integer>();
    前者是传统语法,后者是泛型容器的语法。所谓泛型容器,即指定了容器内成员元素的数据类型的容器。 
    前者创建了List接口的对象,实际上是ArrayList类的实例。
    后者创建了List接口的对象,该对象的所有内部成员元素都是Integer类型的。(与之相比较的是前者的所有成员元素都是Object类型的。)

  二、判断是否为空
    list.isEmpty();
    这是判断容器是否为空,返回值是boolean类型,如果是true就表示容器是空的(没有成员元素),否则表示不为空(即已有至少一个成员元素)。 

  三、计算容器大小
    int size = list.size(); 
    这是返回容器的大小,即容器内成员元素的个数,返回值是整数类型。

  四、添加元素
    boolean success = list.add(obj);
    list.add(2, obj);
    这是向List容器中添加元素,有以下几点值得注意:
    1、添加的元素类型:如果是泛型容器,这个参数obj必须是指定的类型(或其子类,这个类型在创建容器时指定);如果不是,那么这个obj只要是Object类(或其子类)就行。
    2、前者返回值是boolean类型,表示此次添加操作是否成功,后者没有返回值。
    3、前者把新元素添加到List末尾,后者把新元素添加到指定的位置(下标,从0算起),该位置及其之后的元素都向后移动。
    
  五、取其中的元素
    list.get(2);
    输入参数是下标,即第几个元素,从0算起。至于返回值,要看List容器是否泛型,如果是泛型容器,那就返回指定类型的对象,否则返回的是Object类型的对象。

  六、删除元素
    list.remove(2);
    boolean success = list.remove(obj);
  
  前者从List容器中删掉指定下标位置的成员元素,返回值类似五。 
    后者从List容器中删掉obj对象,操作成功返回true。什么情况会不成功呢?容器中没有obj这个对象。

  七、查找
    list.contains(obj);
    list.indexOf(obj);
    前者只看容器中是否存在obj这个对象,有的话返回true,否则返回false。
    后者查找容器中是否存在obj这个对象,有的话返回其下标(整数),否则返回-1。 
 

  八、遍历
    最好的写法是用forEach语法:
    for (Integer a : list){ // 注:Integer是指创建泛型容器时指定的数据类型
    }
    注意:
    1、最好是泛型容器,这种语法还能省掉数据类型转换的麻烦。否则Integer就要换成Object,还是要做数据类型转换。
    2、List容器内的顺序是固定的,所以for循环时,可以看到a是按照list容器的顺序依次遍历的。
    3、这种遍历有一个缺点,就是没有下标,所以需要下标这个值的时候,还是用传统循环遍历好了,遍历语法是:
    for (int i=0; i<list.size(); i++) 
 {
      Integer a = list.get(i);
  
    …… 
    } 
    这样a仍然是遍历时每个成员元素的引用,但是多了一个i是对应的下标。
0 0