妹:打印数组有什么好讲的?

开发 后端
[Ljava.lang.String; 表示字符串数组的 Class 名,@ 后面的是十六进制的 hashCode——这样的打印结果太“人性化”了,一般人表示看不懂!为什么会这样显示呢?

[[399424]]

“哥,之前听你说,数组也是一个对象,但 Java 中并未明确的定义这样一个类。”看来三妹有在用心地学习。

“是的,因此数组也就没有机会覆盖 Object.toString() 方法。如果尝试直接打印数组的话,输出的结果并不是我们预期的结果。”我接着三妹的话继续说。

“那怎么打印数组呢?”三妹心有灵犀地把今天的核心问题提了出来。

“首先,我们来看一下,为什么不能直接打印数组,直接打印的话,会出现什么问题。”

来看这样一个例子。

  1. String [] cmowers = {"沉默","王二","一枚有趣的程序员"}; 
  2. System.out.println(cmowers); 

程序打印的结果是:

  1. [Ljava.lang.String;@3d075dc0 

[Ljava.lang.String; 表示字符串数组的 Class 名,@ 后面的是十六进制的 hashCode——这样的打印结果太“人性化”了,一般人表示看不懂!为什么会这样显示呢?查看一下 java.lang.Object 类的 toString() 方法就明白了。

  1. public String toString() { 
  2.     return getClass().getName() + "@" + Integer.toHexString(hashCode()); 

再次证明,数组虽然没有显式定义成一个类,但它的确是一个对象,继承了祖先类 Object 的所有方法。

“哥,那为什么数组不单独定义一个类来表示呢?就像字符串 String 类那样呢?”三妹这个问题让人头大,但也好解释。

“一个合理的说法是 Java 将其隐藏了。假如真的存在这么一个类,就叫 Array.java 吧,我们假想一下它真实的样子,必须得有一个容器来存放数组的每一个元素,就像 String 类那样。”一边回答三妹,我一边打开了 String 类的源码。

  1. public final class String 
  2.     implements java.io.Serializable, Comparable<String>, CharSequence { 
  3.     /** The value is used for character storage. */ 
  4.     private final char value[]; 

“最终还是要用类似一种数组的形式来存放数组的元素,对吧?这就变得很没有必要了,不妨就把数组当做是一个没有形体的对象吧!”

“好了,不讨论这个了。”我怕话题扯远了,扯到我自己也答不出来就尴尬了,赶紧把三妹的思路拽了回来。

“我们来看第一种打印数组的方法,使用时髦一点的 Stream 流。”

第一种形式:

  1. Arrays.asList(cmowers).stream().forEach(s -> System.out.println(s)); 

第二种形式:

  1. Stream.of(cmowers).forEach(System.out::println); 

第三种形式:

  1. Arrays.stream(cmowers).forEach(System.out::println); 

打印的结果如下所示。

  1. 沉默 
  2. 王二 
  3. 一枚有趣的程序员 

没错,这三种方式都可以轻松胜任本职工作,并且显得有点高大上,毕竟用到了 Stream,以及 lambda 表达式。

“当然了,也可以使用比较土的方式,for 循环。甚至 for-each 也行。”

  1. for(int i = 0; i < cmowers.length; i++){ 
  2.     System.out.println(cmowers[i]); 
  3.  
  4. for (String s : cmowers) { 
  5.     System.out.println(s); 

“哥,你难道忘了上一篇在讲 Arrays 工具类的时候,提到过另外一种方法 Arrays.toString() 吗?”三妹看我一直说不到点子上,有点着急了。

“当然没有了,我认为 Arrays.toString() 是打印数组的最佳方式,没有之一。”我的情绪有点激动。

Arrays.toString() 可以将任意类型的数组转成字符串,包括基本类型数组和引用类型数组。该方法有多种重载形式。

使用 Arrays.toString() 方法来打印数组再优雅不过了,就像,就像,就像蒙娜丽莎的微笑。

(三妹看到这么一副图的时候忍不住地笑了)

“三妹,你不要笑,来,怀揣着愉快的心情看一下代码示例。”

  1. String [] cmowers = {"沉默","王二","一枚有趣的程序员"}; 
  2. System.out.println(Arrays.toString(cmowers)); 

程序打印结果:

  1. [沉默, 王二, 一枚有趣的程序员] 

哇,打印格式不要太完美,不多不少!完全是我们预期的结果:[] 表明是一个数组,, 点和空格用来分割元素。

“哥,那如果我想打印二维数组呢?”

“可以使用 Arrays.deepToString() 方法。”

  1. String[][] deepArray = new String[][] {{"沉默""王二"}, {"一枚有趣的程序员"}}; 
  2. System.out.println(Arrays.deepToString(deepArray)); 

打印结果如下所示。

  1. [[沉默, 王二], [一枚有趣的程序员]] 

“说到打印,三妹,哥给你提醒一点。阿里巴巴的 Java 开发手册上有这样一条规约,你看。”

“什么是 POJO 呢,就是 Plain Ordinary Java Object 的缩写,一般在 Web 应用程序中建立一个数据库的映射对象时,我们称它为 POJO,这类对象不继承或不实现任何其它 Java 框架的类或接口。”

“对于这样的类,最好是重写一下它的 toString() 方法,方便查看这个对象到底包含了什么字段,好排查问题。”

“如果不重写的话,打印出来的 Java 对象就像直接打印数组的那样,一串谁也看不懂的字符序列。”

“可以借助 Intellij IDEA 生成重写的 toString() 方法,特别方便。”

“好的,哥,我记住了。以后遇到的话,我注意下。你去休息吧,我来敲一下你提到的这些代码,练一练。”

“OK,我走,我走。”

本文转载自微信公众号「沉默王二」,可以通过以下二维码关注。转载本文请联系沉默王二公众号。

 

责任编辑:武晓燕 来源: 沉默王二
相关推荐

2021-05-10 11:38:07

Java数组IDEA

2009-08-26 13:41:58

PHP操作Imagic

2023-09-12 14:02:30

数组vector

2022-10-27 19:32:20

切片golang数组

2009-11-18 17:29:25

PHP数组

2015-11-12 15:39:53

程序员笑话

2023-09-26 22:15:49

JavaScrip开发

2021-07-30 09:32:55

JavaEquals

2012-11-08 09:37:55

IT公司IT女生编程语言

2011-05-03 16:40:29

喷墨打印机打印机墨盒维修

2023-03-28 07:03:15

gRPCMetadata

2020-12-09 05:19:35

static关键字Java

2021-06-06 20:56:48

Java内存 intern

2009-09-24 10:23:41

打印服务器

2021-07-09 06:48:29

数组存储内存

2020-10-05 21:38:35

pythonprettyprintpprint

2021-07-08 22:43:41

ThrowThrowsJava

2021-08-23 06:22:00

PaaSDevOps平台即服务

2017-05-08 16:13:33

深度学习神经网络深度

2020-10-29 10:28:31

Java数据类型
点赞
收藏

51CTO技术栈公众号