黑马程序员技术交流社区

标题: JAVA容器1 [打印本页]

作者: lilongbin2016    时间: 2016-12-10 22:39
标题: JAVA容器1
一、 数组

1、数组是保存一组对象的最有效的方式。但数组有固定的尺寸而受限(p216)

2、数组与其他种类的容器之间的区别有三方面:效率、类型和保存基本类型的能力。在Java中,数组是一种效率最高的存储和随机访问对象引用序列的方式。数组就是一个简单的线性序列,这使得元素访问非常快速。但是为这种速度所付出的代价就是数组对象的大小被固定,并且在其生命周期中不可改变。

3、无论使用哪种类型的数组,数组标识符其实只是一个引用,指向在堆中创建的一个真实对象,这个(数组)对象用以保存指向其他对象的引用。
4、对象数组和基本类型数组在使用上几乎是相同的,唯一的区别就是对象数组保存的是引用,基本类型数组直接保存基本类型的值。新建一个对象数组未赋值时自动初始化为null,同样基本类型的数组如果是数值型的,就被自动初始化为0,如果是字符型(char)的,就被自动初始化为(char)O,如果是布尔型(boolean),就被自动初始化为false。
5、多维数组



//创建多维数组
public static void main(String[] args) {
        int[][] a = {{ 1, 2, 3}, { 4, 5, 6}};
        System.out.println(Arrays.deepToString(a));
        //deepToString返回指定数组“深层内容”的字符串表示形式。如果数组包含作为元素的其他数组,
        //则字符串表示形式包含其内容等。此方法是为了将多维数组转换为字符串而设计的。
               
        int[][][] b = new int[2][2][4];
        System.out.println(Arrays.deepToString(b));
}

public static void main(String[] args) {
        Integer[][] a;
        a = new Integer[6][];
        for (int i = 0; i < a.length; i++) {
            a[i] = new Integer[3];
            for (int j = 0; j < a[i].length; j++)
                a[i][j] = i * j; // Autoboxing
        }
        System.out.println(Arrays.deepToString(a));
<span style="font-family:Microsoft YaHei;">//</span>Output: [[0, 0, 0], [0, 1, 2], [0, 2, 4], [0, 3, 6], [0, 4, 8], [0, 5, 10]]
}


6、数组与泛型

通常,数组与泛型不能很好地结合。你不能实例化具有参数化类型的数组,擦除会移除参数类型信息,而数组必须知道它们所持有的确切类型,以强制保证类型安全。但是,你可以参数化数组本身的类型:


//类泛型
class ClassParameter<T> {
        public T[] f(T[] arg) {
                return arg;
        }
}

class MethodParameter {
        // 方法泛型
        public static <T> T[] f(T[] arg) {
                return arg;
        }
}

public class ParameterizedArrayType {
        public static void main(String[] args) {
                Integer[] ints = { 1, 2, 3, 4, 5 };
                Double[] doubles = { 1.1, 2.2, 3.3, 4.4, 5.5 };
               
                Integer[] ints2 = new ClassParameter<Integer>().f(ints);
                Double[] doubles2 = new ClassParameter<Double>().f(doubles);
               
                ints2 = MethodParameter.f(ints);
                doubles2 = MethodParameter.f(doubles);
               
                System.out.println(Arrays.deepToString(ints2));
        }
}

7、Arrays实用功能
Arrays有六个基本方法:

(1)equals()用于比较两个数组是否相等(deepEquals()用于多维数组),

(2)fill()

(3)sort()用于对数组排序

(4)binarySearch()使用二分搜索法在已经排序的数组中查找元素,必须在进行此调用前对数组进行排序,如果没有对数组进行排序,则结果是不确定的。如果数组包含多个带有指定值的元素,则无法保证找到的是哪一个。如果元素包含在数组中,则返回搜索元素的索引,否则返回搜索键的索引(好像就是得到搜索数组的长度的负值);否则返回(-(插入点) - 1)。插入点 被定义为将键插入数组的那一点:即第一个大于此键的元素索引,如果数组中的所有元素都小于指定的键,则为a.length。注意,这保证了当且仅当此键被找到时,返回的值将 >= 0 。

(5)toString()产生数组的String表示

(6)hashCode()产生数组的散列码

(7)asList()转变成List容器

(8)copyOf

(9)System.arraycopy(),该方法不会执行自动包装和自动拆包,两个数组必须具有相同的确切类型。


8、利用Comparable进行比较

利用该接口来进行比较很简单,只需实现该接口然后实现compartTo方法即可。如果当前对象小于参数则返回负值,如果相等则返回零,如果当前对象大于参数则返回正值。




二、 集合类

集合类,也称Java容器类

1、Java容器类类库的用途是“保存对象”,并将其划分为两个不同的概念。(p219)
     (1)Collection。该容器类类库包括List、Set、Queue。List必须按照插入的顺序保存元素,Set不能有重复的元素,Queue按照排队规则来确定对象产生的顺序(通常与他们被插入的顺序相同)。

    (2)Map。它被称为“关联数组”,因为它将某些对象与另外一些对象关联在一了一起。Map是强大的编程工具。

2、Collection接口概括了序列的概念(一种存放一组对象的方式。)(p219)

3、每个java.util容器都有其自己的Abstract类,它们提供了该容器的部分实现。

4、为了创建只读的Map,可以继承AbstractMap并实现entrySet(),

     为了创建只读的Set,可以继承AbstractSet并实现iterator()和size(),

    为了创建只读的List,可以继承AbstractList并实现get()和size()。

3、在java.util包中的Arrays和Collections类中都有很多实用方法。

public static void main(String[] args) {
        Collection<Integer> collection = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5,6,7,8,9,0));
        Integer[] moreInts = {43,82,98,90,21};
        //Arrays.asList()方法接收一个数组或是一个用逗号分隔的元素列表(使用可变参数) --> 转成List对象
        collection.addAll(Arrays.asList(moreInts));

        //Collections.addAll()方法接受一个Collection对象,以及一个数组或者是可变参数,将元素添加到Collection中
        Collections.addAll(collection, 11,12,34,843,90,80,3);
        Collections.addAll(collection, moreInts);
       
        List<Integer> list = Arrays.asList(73,92,84,93,26,78,79);
        list.set(1, 0);//将索引为1的元素的值修改为0
}
4、完整的容器分类
      
由上图可以看出,Hashtable、Vector、Stack的特征是,它们是过去遗留下来的类,目的是为了支持老的程序(最好不要在新的程序中使用它们)

不同类型的Queue只在它们接受和产生数值的方式上有所差异



List


1、ArrayList,它长于随机访问元素,但是在List的中间插入和移除元素时比较慢(p223)

2、LinkedList,它通过代价较低的在List中间进行的插入和删除操作,提供了优化的顺序访问。但是在随机访问方面相对比较慢,但是它的特性集较ArrayList更大。

LinkedList还添加了可以使其用作栈、队列或双端队列的方法。(p228)

LinkedList具有能够直接实现栈的所有功能的方法

3、如果要进行大量的随机访问,就使用ArrayList;如果要经常从表中间插入或删除元素,则应该使用LinkedList。(p245)
4、Arrays.asList会生成一个List,它基于一个固定大小的数组,仅支持那些不会改变数组大小的操作,因此add等操作方法会抛出一个不可选操作的异常。我们应该吧Arrays.asList的结果作为参数传递给任何Collection(或者使用addAll()方法,或Collections.addAll()静态方法),这样可以生成允许使用所有的方法的普通容器。




Stack

1、“栈”通常是指“后进先出”(LIFO)的容器。有时栈也被称为叠加栈,因为最后“压入”栈的元素,第一个弹出栈。





Set

1、

  Set不能保存重复的元素,Set中最常被使用的是测试归属性,你可以很容易地询问某个对象是否在某个Set中。正因为如此,查找就成为了Set中最重要的操作。Set具有与Collection完全一样的接口,因此没有任何额外的功能,不像List会有两个不同的List。实际上Set就是Collection,只是行为不同。Set是基于对象的值来确定归属的  






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2