Java进阶——容器

栏目: Java · 发布时间: 9年前

内容简介:Java进阶——容器

Java中有一些对象被称为 容器 ( container ) 。容器中可以包含多个对象,每个对象称为容器中的一个元素。容器是用对象封装的 数据结构 (data structure)。

Java进阶——容器

充满梦想的容器

不同的数据结构有不同的组织元素的方式,也可以有不同的操作。根据具体实施的不同,数据结构的操作效率也各有差别。Java中的容器也是这样。我们要选择适当的容器,以应对变化的需求。

数组

数组(array) 是最常见的数据结构。数组是相同类型元素的有序集合,并有固定的大小(可容纳固定数目的元素)。数组可以根据 下标(index) 来随机存取(random access)元素。在内存中,数组通常是一段连续的存储单元。

Java支持数组这一数据结构。我们需要说明每个数组的类型和大小。如下:


public class Test
{
    public static void main(String[] args)
    {
        Human[] persons = new Human[2];              // array size 2
        persons[0] = new Human(160);
        persons[1] = new Human(170);

        int[] a = {1, 2, 3, 7, 9};                   // array size 5
        System.out.println(a[2]);

        String[] names = {"Tom", "Jerry", "Luffy"};  // array size 3
        System.out.println(names[0]);
    }
}

在说明类型时,在类型说明(Human)后面增加一个 [] ,来说明是一个数组。使用 new 创建容器时,需要说明数组的大小。

我们可以使用  数组名[下标] 的方式来调用某个元素。我们可以逐个的初始化数组的元素,也可以在声明的同时使用 {} 初始化数组。

对于非基本类型的数组,比如Human[],数组中存储的是对象的引用。

我们可以调用 System.arraycopy() 方法来有效的复制数组:


public class Test
{
    public static void main(String[] args)
    {
        int[] aFrom = {1, 2, 3, 7, 9}; // array size 5
        int[] aTo  = new int[3];
        System.arraycopy(aFrom, 1, aTo, 0, 3);
        System.out.println(aTo[1]);
    }
}

System.arraycopy()中, aFrom 为想要复制出去的数组, aTo 为想要复制到的数组, 1 为aFrom的想要复制出去的元素起始位置, 0 为aTo中想要存储复制来元素的起始位置, 3 为所要复制的元素总数。

Collection

表(List)集合(Set) 是java.util中定义的两个接口(interface)。这两个接口都继承自Collection接口。通过实施接口,我们可以获得相应的容器。

我们之前都是使用类(class)来说明引用的类型。事实上,我们也可以用接口(interface)来说明引用的类型。 该类型引用所指向的对象必须实施了该接口

我们先来使用 表(List) 容器。List是 有序 的元素集合,所以可以使用下标来说明元素的位置。集合中的 元素可以相等 :


import java.util.*;

public class Test
{
    public static void main(String[] args)
    {
        List<String> l1 = new ArrayList<String>();
        l1.add("good");
        l1.add("bad");
        l1.add("shit");
        l1.remove(0);
        System.out.println(l1.get(1));
        System.out.println(l1.size());
    }
}

当我们在定义接口和创建容器时,我们使用 <class> 的方式来说明容器中所能容纳元素的类型。我们将只能在容器中放入class类及其衍生类的对象。

容器的引用为List类型,但容器的实施为ArrayList类。这里是将接口与实施分离。事实上,同一种抽象数据结构(ADT)都可以有多种实施方法(比如栈可以实施为数组和链表)。这样的分离允许我们更自由的选择ADT的实施方式。

我们可以定义<Object>类型的容器。由于 Java 中的所有类都继承自Object类,这样的容器实际上可以放入任意类型的对象。

在上面的程序中,容器为String类型。我们用

  • add() 方法加入新的元素
  • get() 方法可以获取容器中的元素,传递一个整数下标作为参数
  • remove() 方法可以删除容器中的元素,传递一个整数下标作为参数。(有另一个remove(),传递元素自身作为参数)
  • size() 方法用来返回容器中元素的总数。

List的官方文档

集合(set) 也是元素的集合。集合中 不允许有等值的元素 ,集合的元素 没有顺序 :


import java.util.*;

public class Test
{
    public static void main(String[] args)
    {
        Set<Integer> s1 = new HashSet<Integer>();
        s1.add(4);
        s1.add(5);
        s1.add(4);
        s1.remove(5);
        System.out.println(s1);
        System.out.println(s1.size());
    }
}

重复加入的元素4只被放入容器一次。由于Set是无序的,在 remove() 中,我们直接传递目标元素本身作为参数。

Set的官方文档

List和Set都继承自Collection接口。Collection代表了对象的集合。上面List和Set接口中的许多方法实际上继承自Collection,比如:

add("good") 加入元素

size() 返回元素的总数

contains("bad") 是否包含元素

remove("good")  删除元素

Collection的官方文档

Collection还有一个 iterator() 的方法。该方法将Collection容器封装成 循环器(Iterator) 。循环器是元素的集合,它有next()方法,用于每次返回一个元素,直到循环器中元素穷尽。


import java.util.*;

public class Test
{
    public static void main(String[] args)
    {
        List<Integer> l1 = new ArrayList<Integer>();
        l1.add(4);
        l1.add(5);
        l1.add(2);
        Iterator i = l1.iterator();
        while(i.hasNext()) {
            System.out.println(i.next());
        }
    }
}

Iterator的官方文档

Map

Map是 键值对 的集合。Map中的每个元素是一个键值对,即一个 键(key) 和它对应的 对象值(value) 。对于Map容器,我们可以通过键来找到对应的对象。

哈希表是Map常见的一种实施方式,参考 纸上谈兵: 哈希表 (hash table)

我们需要声明Map的键和值的类型。我们下面实施一个HashMap:


import java.util.*;

public class Test
{
    public static void main(String[] args)
    {
        Map<String, Integer> m1 = new HashMap<String, Integer>();
        m1.put("Vamei", 12);
        m1.put("Jerry", 5);
        m1.put("Tom", 18);
        System.out.println(m1.get("Vamei"));

    }
}

在Map中,我们使用 put() 方法来添加元素,用 get() 方法来获得元素。 

Map还提供了下面的方法,来返回一个Collection:

keySet()  将所有的键转换为Set

values()  将所有的值转换为List

总结

Java中,容器的接口与实施分离。这给了Java程序员更大的选择自由,当然,也为编程增加了难度。

接口为我们提供了合法的操作。在效果层面上看,不同的实施都有相同的效果。当然,不同的情境下,实施的细节将决定运行效率。

最后,是我们提到的各个类与接口的关系:

Java进阶——容器

Java学习交流QQ群:523047986  禁止闲聊,非喜勿进!


以上所述就是小编给大家介绍的《Java进阶——容器》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Effective Engineer

The Effective Engineer

Edmond Lau / The Effective Bookshelf, Palo Alto, CA. / 2015-3-19 / USD 39.00

Introducing The Effective Engineer — the only book designed specifically for today's software engineers, based on extensive interviews with engineering leaders at top tech companies, and packed with h......一起来看看 《The Effective Engineer》 这本书的介绍吧!

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具