打印 Java 数组的最简单方法是什么?

Posted HuntsBot

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了打印 Java 数组的最简单方法是什么?相关的知识,希望对你有一定的参考价值。

问:

在 Java 中,数组不会覆盖 toString(),因此如果您尝试直接打印一个,则会得到 className + ‘@’ + 数组 hashCode 的十六进制,如 Object.toString() 所定义:

int[] intArray = new int[] 1, 2, 3, 4, 5;
System.out.println(intArray);     // prints something like '[I@3343c8b3'

但通常情况下,我们实际上想要更像 [1, 2, 3, 4, 5] 的东西。最简单的方法是什么?以下是一些示例输入和输出:

// Array of primitives:
int[] intArray = new int[] 1, 2, 3, 4, 5;
//output: [1, 2, 3, 4, 5]

// Array of object references:
String[] strArray = new String[] "John", "Mary", "Bob";
//output: [John, Mary, Bob]

答1:

huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。

从 Java 5 开始,您可以将 Arrays.toString(arr) 或 Arrays.deepToString(arr) 用于数组中的数组。请注意,Object[] 版本对数组中的每个对象调用 .toString()。输出甚至以您要求的确切方式进行装饰。

例子:

简单数组:String[] array = new String[] “John”, “Mary”, “Bob”; System.out.println(Arrays.toString(array));输出:[约翰,玛丽,鲍勃]

嵌套数组:String[][] deepArray = new String[][] “John”, “Mary”, “Alice”, “Bob”; System.out.println(Arrays.toString(deepArray)); //输出:[[Ljava.lang.String;@106d69c, [Ljava.lang.String;@52e922] System.out.println(Arrays.deepToString(deepArray));输出:[[约翰,玛丽],[爱丽丝,鲍勃]]

双数组:双[] 双数组 = 7.0, 9.0, 5.0, 1.0, 3.0 ; System.out.println(Arrays.toString(doubleArray));输出:[7.0, 9.0, 5.0, 1.0, 3.0]

int 数组:int[] intArray = 7, 9, 5, 1, 3 ; System.out.println(Arrays.toString(intArray));输出:[7、9、5、1、3]

如果我们有一个字符串数组,并且想要简单的输出怎么办?比如:String[] array = "John", "Mahta", "Sara",我们想要这个没有括号和逗号的输出:John Mahta Sara?

@Hengameh:还有其他几种方法可以做到这一点,但我最喜欢的是这个: javahotchocolate.com/notes/java.html#arrays-tostring 。

仅供参考,Arrays.deepToString() 仅接受 Object [](或扩展 Object 的类数组,例如 Integer,因此它不适用于 int [] 类型的原始数组。但 Arrays.toString() 有效适用于原始数组。

@Hengameh 有一种专用的方法。 System.out.println(String.join(" ", new String[]"John", "Mahta", "Sara")) 将打印 John Mahta Sara。

不要忘记“import java.util.Arrays;”

答2:

huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感

始终首先检查标准库。

import java.util.Arrays;

然后尝试:

System.out.println(Arrays.toString(array));

或者如果您的数组包含其他数组作为元素:

System.out.println(Arrays.deepToString(array));

@Hengameh 如今使用 Java 8:String.join(" ", Arrays.asList(array))。 doc

答3:

huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!

很高兴知道,但是,至于“总是先检查标准库”,我永远不会偶然发现 Arrays.toString( myarray ) 的把戏

–因为我专注于 myarray 的类型以了解如何执行此操作。我不想遍历这件事:我想要一个简单的调用来使它类似于我在 Eclipse 调试器中看到的那样,而 myarray.toString() 只是没有这样做。

import java.util.Arrays;
.
.
.
System.out.println( Arrays.toString( myarray ) );

答4:

huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感

在 JDK1.8 中,您可以使用聚合操作和 lambda 表达式:

String[] strArray = new String[] "John", "Mary", "Bob";

// #1
Arrays.asList(strArray).stream().forEach(s -> System.out.println(s));

// #2
Stream.of(strArray).forEach(System.out::println);

// #3
Arrays.stream(strArray).forEach(System.out::println);

/* output:
John
Mary
Bob
*/

答5:

huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式

数组.toString

作为直接答案,使用 Arrays.toString 和 Arrays.deepToString 方法的 the solution provided by several, including @Esko 是最好的。

Java 8 - Stream.collect(joining()), Stream.forEach

下面我尝试列出一些其他建议的方法,并尝试进行一些改进,其中最值得注意的添加是使用 Stream.collect 运算符,使用 joining Collector 来模仿 String.join 是什么正在做。

int[] ints = new int[] 1, 2, 3, 4, 5;
System.out.println(IntStream.of(ints).mapToObj(Integer::toString).collect(Collectors.joining(", ")));
System.out.println(IntStream.of(ints).boxed().map(Object::toString).collect(Collectors.joining(", ")));
System.out.println(Arrays.toString(ints));

String[] strs = new String[] "John", "Mary", "Bob";
System.out.println(Stream.of(strs).collect(Collectors.joining(", ")));
System.out.println(String.join(", ", strs));
System.out.println(Arrays.toString(strs));

DayOfWeek [] days =  FRIDAY, MONDAY, TUESDAY ;
System.out.println(Stream.of(days).map(Object::toString).collect(Collectors.joining(", ")));
System.out.println(Arrays.toString(days));

// These options are not the same as each item is printed on a new line:
IntStream.of(ints).forEach(System.out::println);
Stream.of(strs).forEach(System.out::println);
Stream.of(days).forEach(System.out::println);

如果你使用 IntStream.of(ints).forEach(System.out::print);我不认为它会在新行打印..

答6:

HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com

从 Java 8 开始,还可以利用 String class 提供的 join() 方法打印出数组元素,不带括号,并由选择的分隔符分隔(这是下面示例中的空格字符):

String[] greeting = "Hey", "there", "amigo!";
String delimiter = " ";
String.join(delimiter, greeting) 

输出将是“嘿,朋友!”。

huntsbot.com精选全球7大洲远程工作机会,涵盖各领域,帮助想要远程工作的数字游民们能更精准、更高效的找到对方。

答7:

huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。

在 Java 8 之前

我们可以使用 Arrays.toString(array) 打印一维数组,使用 Arrays.deepToString(array) 打印多维数组。

爪哇 8

现在我们有了 Stream 和 lambda 的选项来打印数组。

打印一维数组:

public static void main(String[] args) 
    int[] intArray = new int[] 1, 2, 3, 4, 5;
    String[] strArray = new String[] "John", "Mary", "Bob";

    //Prior to Java 8
    System.out.println(Arrays.toString(intArray));
    System.out.println(Arrays.toString(strArray));

    // In Java 8 we have lambda expressions
    Arrays.stream(intArray).forEach(System.out::println);
    Arrays.stream(strArray).forEach(System.out::println);


输出是:

[1, 2, 3, 4, 5] [约翰,玛丽,鲍勃] 1 2 3 4 5 约翰玛丽鲍勃

打印多维数组 如果我们想打印多维数组,我们可以使用 Arrays.deepToString(array) 作为:

public static void main(String[] args) 
    int[][] int2DArray = new int[][]  11, 12,  21, 22, 31, 32, 33 ;
    String[][] str2DArray = new String[][] "John", "Bravo" , "Mary", "Lee", "Bob", "Johnson" ;

    //Prior to Java 8
    System.out.println(Arrays.deepToString(int2DArray));
    System.out.println(Arrays.deepToString(str2DArray));

    // In Java 8 we have lambda expressions
    Arrays.stream(int2DArray).flatMapToInt(x -> Arrays.stream(x)).forEach(System.out::println);
    Arrays.stream(str2DArray).flatMap(x -> Arrays.stream(x)).forEach(System.out::println);
 

现在要注意的是方法 Arrays.stream(T[]),在 int[] 的情况下返回 Stream<int[]>,然后方法 flatMapToInt() 将流的每个元素映射到通过应用提供的映射函数生成的映射流的内容到每个元素。

输出是:

[[11, 12], [21, 22], [31, 32, 33]] [[John, Bravo], [Mary, Lee], [Bob, Johnson]] 11 12 21 22 31 32 33 John Bravo Mary李·鲍勃·约翰逊

答8:

huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感

如果您使用的是 Java 1.4,则可以改为:

System.out.println(Arrays.asList(array));

(当然,这也适用于 1.5+。)

不幸的是,这只适用于对象数组,而不适用于基元数组。

答9:

huntsbot.com – 程序员副业首选,一站式外包任务、远程工作、创意产品分享订阅平台。

Arrays.deepToString(arr) 仅打印在一行上。

int[][] table = new int[2][2];

要真正将表格打印为二维表格,我必须这样做:

System.out.println(Arrays.deepToString(table).replaceAll("],", "]," + System.getProperty("line.separator")));

似乎 Arrays.deepToString(arr) 方法应该采用分隔符字符串,但不幸的是它没有。

也许使用 System.getProperty("line.separator");而不是 \\r\\n 所以它也适用于非 Windows。

答10:

huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感

for(int n: someArray) 
    System.out.println(n+" ");


这样你最终会得到一个空白空间;)

@ matthiad .. 这一行将避免以空白结尾 System.out.println(n+ (someArray.length == n) ? "" : " ");

@MuhammadSuleman 那不起作用,因为这是一个 for-each 循环。 n 是数组中的实际值,而不是索引。对于常规的 for 循环,它也是 (someArray.length - 1) == i,因为它会在 i 等于数组长度时中断。

答11:

huntsbot.com提供全网独家一站式外包任务、远程工作、创意产品分享与订阅服务!

在 Java 中打印数组的不同方法:

简单方式 List list = new ArrayList(); list.add(“一个”); list.add(“两个”); list.add(“三”); list.add(“四”); // 在控制台打印列表 System.out.println(list);

输出:[一、二、三、四]

使用 toString() String[] array = new String[] “One”, “Two”, “Three”, “Four” ; System.out.println(Arrays.toString(array));

输出:[一、二、三、四]

打印数组 String[] arr1 = new String[] “Fifth”, “Sixth” ; String[] arr2 = new String[] “Seventh”, “Eight” ; String[][] arrayOfArray = new String[][] arr1, arr2 ; System.out.println(arrayOfArray); System.out.println(Arrays.toString(arrayOfArray)); System.out.println(Arrays.deepToString(arrayOfArray));

输出:[[Ljava.lang.String;@1ad086a [[Ljava.lang.String;@10385c1, [Ljava.lang.String;@42719c] [[第五、第六]、[第七、第八]]

资源:Access An Array

原文链接:https://www.huntsbot.com/qa/yOP4/whats-the-simplest-way-to-print-a-java-array?lang=zh_CN&from=csdn

一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会

使用 std::ostream 打印可变参数包的最简单方法是啥?

【中文标题】使用 std::ostream 打印可变参数包的最简单方法是啥?【英文标题】:What is the easiest way to print a variadic parameter pack using std::ostream?使用 std::ostream 打印可变参数包的最简单方法是什么? 【发布时间】:2015-02-07 02:49:22 【问题描述】:

使用std::ostream 打印参数包的最简单方法是什么,以逗号分隔?

例子:

template<typename... Args>
void doPrint(std::ostream& out, Args... args)
   out << args...; // WRONG! What to write here?


// Usage:
int main()
   doPrint(std::cout,34,"bla",15); // Should print: 34,bla,15

注意: 可以假设 &lt;&lt; 运算符的相应重载可用于所有类型的参数包。

【问题讨论】:

在 C++17 中,你会说 (out &lt;&lt; ... &lt;&lt;&lt; args); 注意:这不是重复的——foo &lt;&lt; X &lt;&lt; Y; 通常与foo &lt;&lt; X; foo &lt;&lt; Y; 不同,尤其是当foo 具有诸如打开磁盘上的文件等副作用时。 @MSalters,foo &lt;&lt; X &lt;&lt; Y 也没有指定 XY 的评估顺序(即在 C++17 之前) 【参考方案1】:

没有你想要的递归调用和逗号。

在c++11/c++14通过参数包扩展:

template <typename Arg, typename... Args>
void doPrint(std::ostream& out, Arg&& arg, Args&&... args)

    out << std::forward<Arg>(arg);
    using expander = int[];
    (void)expander0, (void(out << ',' << std::forward<Args>(args)), 0)...;

DEMO


在c++17 中使用折叠表达式:

template <typename Arg, typename... Args>
void doPrint(std::ostream& out, Arg&& arg, Args&&... args)

    out << std::forward<Arg>(arg);
    ((out << ',' << std::forward<Args>(args)), ...);

DEMO 2

【讨论】:

这个是最简单的。只是看起来怪怪的,呵呵。 @GermánDiago en.cppreference.com/w/cpp/language/parameter_pack 给出了一个类似的例子:int dummy[sizeof...(Ts)] = (std::cout &lt;&lt; args, 0)... ; 附带说明,您可以跳过using 声明,直接写(void)(int[])(std::cout &lt;&lt; ',' &lt;&lt; std::forward&lt;Args&gt;(args)), 0)...;。您也不需要大括号中的第一个零或内部 void 演员表。 @AlexanderRevo insertingostream 意味着将参数传递给operator&lt;&lt; 的某个重载。你永远不知道操作员期望什么参数类型 我的 C++ 一定已经过时了。我根本无法解析。【参考方案2】:

在 C++17 中,将有一种更简单的方法(正如 Kerrek SB 在 cmets 中所暗示的那样;这实际上出现在 N4606,第一个后 C++14 草案中),称为 fold expressions

代码是:

(out << ... << args);

而模式expression op...op parameter-pack称为二元左折叠,其定义等价于@987654326 @ expression op arg1) op arg2) op arg3) .... op argN.

我认为对于这样的表达式语句来说,外括号并不是绝对必要的,但如果折叠表达式是另一个运算符的操作数,那么它们要么是必需的,要么是一个非常好的主意:)

【讨论】:

使用分隔符:((out &lt;&lt; ", " &lt;&lt; args), ...);【参考方案3】:

通常的答案是定义两个单独的重载,一个空的作为基本情况:

// base case
void doPrint(std::ostream& out) 

template <typename T, typename... Args>
void doPrint(std::ostream& out, T t, Args... args)

    out << t;                // add comma here, see below
    doPrint(out, args...);

当然,在实际代码中,我不会每次都复制参数,而是使用转发引用,但你明白了。

如果您想在每一项之后添加逗号,即使是在最后一项之后,只需将 out &lt;&lt; t 替换为 out &lt;&lt; t &lt;&lt; ','

如果您只想在内部使用逗号,而不是在最后一个元素之后,则需要一个单独的不打印逗号的单参数重载,并且通用重载在包之前采用两个不同的参数,即:

template <typename T>
void doPrint(std::ostream& out, T t)

    out << t;


template <typename T, typename U, typename... Args>
void doPrint(std::ostream& out, T t, U u, Args... args)

    out << t << ',';
    doPrint(out, u, args...);

【讨论】:

你能详细说明一下转发参考吗?我对 C++11 的东西还不是很坚定,但是复制参数似乎有点过头了。 @gexicide:这个网站上有数千个重复项,只需四处搜索。您正在寻找Args &amp;&amp;... argsstd::forward&lt;Args&gt;(args)...【参考方案4】:

参数包扩展仅适用于普通函数调用,不适用于中缀运算符。因此,您需要将s &lt;&lt; x 语法转换为普通函数调用语法f(s, x)

template<class Head>
void print_args_(std::ostream& s, Head&& head) 
    s << std::forward<Head>(head);


template<class Head, class... Tail>
void print_args_(std::ostream& s, Head&& head, Tail&&... tail) 
    s << std::forward<Head>(head);
    print_args_(s, std::forward<Tail>(tail)...);


template<class... Args>
void print_args(Args&&... args) 
    print_args_(std::cout, std::forward<Args>(args)...);

【讨论】:

【参考方案5】:

我知道这是一个老问题,但它对我的问题帮助很大。我根据这篇帖子的答案创建了一个实用程序类,我想分享我的结果。

考虑到我们使用 C++11 或更高版本的 C++,这个类提供了 print 和 println 函数来在调用标准输出流之前组合字符串,避免并发问题。这些是可变参数函数,它们使用模板来打印不同的数据类型。

您可以在我的 github 上查看它在生产者-消费者问题中的用途:https://github.com/eloiluiz/threadsBar

所以,这是我的代码:

class Console 
private:
    Console() = default;

    inline static void innerPrint(std::ostream &stream) 

    template<typename Head, typename... Tail>
    inline static void innerPrint(std::ostream &stream, Head const head, Tail const ...tail) 
        stream << head;
        innerPrint(stream, tail...);
    

public:
    template<typename Head, typename... Tail>
    inline static void print(Head const head, Tail const ...tail) 
        // Create a stream buffer
        std::stringbuf buffer;
        std::ostream stream(&buffer);
        // Feed input parameters to the stream object
        innerPrint(stream, head, tail...);
        // Print into console and flush
        std::cout << buffer.str();
    

    template<typename Head, typename... Tail>
    inline static void println(Head const head, Tail const ...tail) 
        print(head, tail..., "\n");
    
;

比起重载&lt;&lt; 运算符或使用复杂的流函数,我更喜欢这种替代方法。它是一种递归方法,但并不难理解。

【讨论】:

我会更改= delete 中的构造函数。由于只有静态方法,实例化Console对象是没有意义的【参考方案6】:

同样适用于std::wostream 的通用形式:

template <typename CharT, typename Traits>
std::basic_ostream<CharT, Traits> &
Print(std::basic_ostream<CharT, Traits> &out)

    return out;


template <typename CharT, typename Traits, typename T>
std::basic_ostream<CharT, Traits> &
Print(std::basic_ostream<CharT, Traits> &out, T &&t)

    return (out << std::forward<T>(t));


template <typename CharT, typename Traits, typename T, typename... Args>
std::basic_ostream<CharT, Traits> &
Print(std::basic_ostream<CharT, Traits> &out, T &&t, Args &&...args)

    return Print( Print(out, std::forward<T>(t)), std::forward<Args>(args)... );

在常见情况下,我无法使其与 std::endl 一起使用(在特定情况下可以处理 std::endl,例如当它是第一个或最后一个参数时,但不是在常见情况下,尤其是如果单个呼叫中有多个std::endl)。如果您确实需要 std::endl,您仍然可以使用 '\n' 或使用 std::endl 指定模板参数:

Print(std::cout, "hello world", std::endl<char, std::char_traits<char>>);

std::endl'\n' 之间的 differences

如果流在二进制模式下工作,则'\n' 不会转换为编译代码所针对的平台的行尾格式(但在文本模式下仍会转换)。 '\n' 不会用std::flush 刷新流(但如果程序在终端上运行,它仍然是flushes std::cout

所以对我来说可以使用'\n',甚至可以使用preferred。

仍然可以使用其他一些 IO 操纵器:

Print(std::cout, std::hex, 11, '\n');

我还实现了sprintf 对应物,它与可变参数模板一起使用并返回std::string

template <typename CharT = char, typename Traits = std::char_traits<CharT>, typename... Args>
std::basic_string<CharT, Traits>
SPrint(Args &&...args)

    std::basic_stringstream<CharT, Traits> ss;
    Print(ss, std::forward<Args>(args)...);
    return std::move(ss.str());

这里有一些demos。

【讨论】:

以上是关于打印 Java 数组的最简单方法是什么?的主要内容,如果未能解决你的问题,请参考以下文章

将hdf5文件中的uint32数据写入java中的数组的最简单方法是啥?

Java对数组的操作—比較两个数组中的元素是否同样的最简单方法

从Java开始忽略/捕获子进程输出的最简单方法

在Java 8中将整数数组转换为字符串数组的最简单方法[重复]

Java - 从列表/数组中的每个对象获取单个属性的最简单方法?

在 C# 中比较数组的最简单方法