专栏首页沉默王二Java中食之无味弃之可惜的数组

Java中食之无味弃之可惜的数组

在Java的泛型出现之前,只有数组可以用来存储指定类型的对象;在自动装箱机制出现之前,只有数组可以用来存储基本数据类型;也就是说,在泛型和自动装箱机制出现之前,数组在Java当中的分量举足轻重。

况且数组还是一种效率最高的存储和随机访问对象序列的方式,但遗憾的是,数组的长度是固定的——创建它的时候指定长度是6,就只能存储6个元素,当你想放第7个元素时,是无法做到的。

随着计算机硬件能力的提升,开发人员在存储一组数据的时候更愿意使用ArrayList而不是数组。尽管ArrayList内部是通过数组实现的,但与数组相比,它的容量能够自动增长,还有很多数组没有的特性。

可以这么肯定的说,能不使用数组就别使用数组,除非要用数组来改善性能问题。

那为什么还要学习数组呢?因为Java的设计者没有对数组痛下杀手,就像曹操当年并没有扔掉那碗食之无味弃之可惜的鸡肋。

01、创建数组

让我们来给Java数组下一个明确的定义——数组用来存储固定长度同类型元素。

示例如下:

int[] ints = new int[3];
ints[0] = 1;
ints[1] = 2;
ints[2] = 3;

int ints1[] = new int[3];

int[] ints2 = { 1, 2, 3 };

int[] ints相较于int ints1[]是优选的声明方式, int ints1[]风格来自于 C/C++ 语言 ,便于 C/C++ 程序员能够快速地理解Java语言。

数组的创建方式有两种,一种是通过new关键字,同时指定长度,然后通过array[index] = value的方式赋值;另外一种方式是通过{value1, value2, ...}的方式直接创建并同时赋值。

最常见的应用如下(日期的占位符字符串):

private static String[] parsePatterns = { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", "yyyy/MM/dd",
            "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM" };

02、小心length

在使用List和Map的时候,可以直接通过size()方法获取容器的实际大小(长度)。数组也有一个关键字length来获取大小(长度),但意思大不相同。length只表示数组所能够容纳元素的大小,而并非数组的实际大小。

举例如下:

int[] ints = new int[3];
ints[0] = 1;
ints[1] = 2;

System.out.println(ints.length); // 输出3

尽管ints的实际长度为2,但ints.length的长度却为3——要小心了。

03、Arrays工具类

Java的设计者可谓良苦用心,特意为数组设计了一个专属工具类——java.util.Arrays,里面有几个常用的方法我们来介绍一下。

1)sort()

sort()方法用来对数组进行排序,该方法要求数组的元素要实现Comparable接口。如果排序的元素不是String或者基本数据类型,就需要主动实现Comparable接口(基本数据类型和String本身已经实现了Comparable接口)。

示例如下:

String[] strs = {"沉", "默","王", "二"};

Arrays.sort(strs);
System.out.println(Arrays.toString(strs));
// 输出[二, 沉, 王, 默]

sort()方法排序后的结果就是[二, 沉, 王, 默]。

2)binarySearch()

binarySearch()方法用来对数组进行二分查找(返回值所在的下标,未找到的话返回-1),调用该方法之前必须要先排序。

示例如下:

String[] strs = {"沉", "默","王", "二"};

Arrays.sort(strs);
System.out.println(Arrays.binarySearch(strs, "二"));
// 排序后的结果为[二, 沉, 王, 默]
// 二分查找的结果范围0

由于sort()方法排序后的结果为[二, 沉, 王, 默],所以Arrays.binarySearch(strs, "二")返回下标值0。

3)asList()

asList()方法用来将数组转化成List(ArrayList),源码如下:

public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}

那如何将List转化成数组呢?通过List的toArray()方法。可参照下例体验由数组定义方式不同带来的细微差别。

String[] strs = {"沉", "默","王", "二"};

List<String> list = Arrays.asList(strs);
System.out.println(list);
// 输出[沉, 默, 王, 二]

String[] strs1 = new String[list.size()];
System.out.println(Arrays.toString(list.toArray(strs1)));
// 输出 [沉, 默, 王, 二]

String[] strs2 = new String[5];
System.out.println(Arrays.toString(list.toArray(strs2)));
// 输出 [沉, 默, 王, 二, null]

String[] strs3 = new String[1];
System.out.println(Arrays.toString(list.toArray(strs3)));
// 输出 [沉, 默, 王, 二]

String[] strs4 = {};
System.out.println(Arrays.toString(list.toArray(strs4)));
// 输出 [沉, 默, 王, 二]

当声明的数组大小超出List的大小后,toArray()方法会对转换后的数组进行补位(null)。

4)toString()

toString()方法用来将数组进行字符串格式的输出([value1, value2, value3, ...]的格式),源码如下:

public static String toString(Object[] a) {
    if (a == null)
        return "null";

    int iMax = a.length - 1;
    if (iMax == -1)
        return "[]";

    StringBuilder b = new StringBuilder();
    b.append('[');
    for (int i = 0; ; i++) {
        b.append(String.valueOf(a[i]));
        if (i == iMax)
            return b.append(']').toString();
        b.append(", ");
    }
}

本文分享自微信公众号 - 沉默王二(cmower)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-02-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 要想数组用的 6,怎能不懂 java.util.Arrays

    java.util.Arrays 类就是为数组而生的专用工具类,基本上常见的对数组的操作,Arrays 类都考虑到了,这让我由衷地觉得,是时候给该类的作者 Jo...

    沉默王二
  • 除了闹过腥风血雨的fastjosn,你还知道哪些Java解析JSON的利器?

    昨天下午 5 点 10 分左右,我解决掉了最后一个 bug,轻舒一口气,准备关机下班。可这个时候,老板朝我走来,脸上挂着神秘的微笑,我就知道他不怀好意。果不其然...

    沉默王二
  • 灵魂拷问:如何检查Java数组中是否包含某个值 ?

    另外,我想要告诉大家的是,作为程序员,我们千万不要轻视这些基础的知识点。因为基础的知识点是各种上层技术共同的基础,只有彻底地掌握了这些基础知识点,才能更好地理解...

    沉默王二
  • 几个 String 的知识点

    不可变字符对象。 所以每次String对象的改变实际是创建了一个新对象。 String 是 final 的也不能被继承。

    潇洒
  • 第三阶段-Java常见对象:【第七章 正则表达式】

    BWH_Steven
  • java版最新获取抖音无水印视频和背景音乐

    public static void main(String[] args) throws Exception {

    织梦有点东西
  • 企业API接口设计(token、timestamp、sign)之具体实现

    Token:访问令牌access token, 用于接口中, 用于标识接口调用者的身份、凭证,减少用户名和密码的传输次数。一般情况下客户端(接口调用方)需要先向...

    lyb-geek
  • QBC查询

    1、基本语法 session.beginTransaction(); Criteria criteria = session.createCriteria(Pe...

    JMCui
  • 学术全景图:机器学习与自然语言处理

    2017 年是自然语言处理(NLP)和机器学习(ML)非常高产的一年。两个领域持续增长,会议论文数量纷纷打破记录。本文中我将根据个人作者和组织进行更详细的细分。...

    机器人网
  • LitePal——Android数据库框架完整使用手册

    LitePal for Android LitePal是一个开源的Android库,使开发人员使用SQLite数据库非常简单。您无需编写任何SQL语句就可以完...

    郭耀华

扫码关注云+社区

领取腾讯云代金券