创建初始重复数据的二维字符串数组的最有效方法是啥?
Posted
技术标签:
【中文标题】创建初始重复数据的二维字符串数组的最有效方法是啥?【英文标题】:What is the most efficient way to create a 2d string array of initally repetitive data?创建初始重复数据的二维字符串数组的最有效方法是什么? 【发布时间】:2021-05-29 06:14:31 【问题描述】:在 Python 中,通常要定义所述游戏板,我会使用以下代码:
board = [['0','0','0','0','0','0','0','0','0','0'] for i in range(10)]
但是,到目前为止,我能够找到产生相同结果的唯一方法是使用 Java:
public static String[][] board =
"0","0","0","0","0","0","0","0","0","0",
"0","0","0","0","0","0","0","0","0","0",
"0","0","0","0","0","0","0","0","0","0",
"0","0","0","0","0","0","0","0","0","0",
"0","0","0","0","0","0","0","0","0","0",
"0","0","0","0","0","0","0","0","0","0",
"0","0","0","0","0","0","0","0","0","0",
"0","0","0","0","0","0","0","0","0","0",
"0","0","0","0","0","0","0","0","0","0",
"0","0","0","0","0","0","0","0","0","0";
当然必须有更有效的方法来做到这一点。我知道如果它是整数,我可以有效地做到这一点,但考虑到这种情况,它必须是字符串。我原以为 for 循环也可以应用,但我似乎找不到合适的语法;也许它不适用于Java。有什么建议吗?
【问题讨论】:
【参考方案1】:您可以遍历每一行并使用Arrays.fill
:
public static String[][] board = new String[rows][cols];
static
for (String[] row : board) Arrays.fill(row, "0");
Demo
【讨论】:
【参考方案2】:您可以使用嵌套的for
循环来创建 10 行和 10 列。因此,在第一个循环(创建一个“行”)中,您需要添加另一个循环来填充“列”。
String[][] board = new String[10][10];
// 10 rows
for (int i = 0; i < 10; i++)
// 10 columns
for (int j = 0; j < 10; j++)
// Set the value of this row/column
board[i][j] = "0";
这显然不如 Python 的单行解决方案优雅,但它可以满足您的需求。
还有其他方法可以做到这一点(例如在每个循环中将一个完整的 10 位数组添加到 board
数组),但我发现这对于可扩展性和可读性来说是最好的。
为了更清楚起见,如果您将来可能需要更改行数或列数,最好将这些值移动到变量中并改用它们:
int rows = 10;
int cols = 10;
String[][] board = new String[rows][cols];
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; i++)
board[i][j] = "0";
这样你只需要更新变量而不是修改for
循环和数组声明。
【讨论】:
哦,我明白了。所以,我将板定义为 10x10,然后返回并将值重置为“0”,允许它们用作字符串......对吗? 假设您提前知道确切的尺寸,是的。不过,到目前为止,这里的其他答案在代码行方面可能更有效。这真的取决于什么对你来说更具可读性。 它始终是相同的确切尺寸是的。唯一要改变的是他们的价值观。可读性在这里有些重要,我相信您的解决方案似乎是我见过的最好的。非常感谢您的解决方案;事实证明,在 Python 和 Java 之间转换很困难。 这基本上是教科书的迭代方法。如果您打算使用嵌套的 for 循环,使用经典的迭代样式直接对数组值进行操作,那么这将尽可能简单明了。 @M.Justin 是的,这正是我想要的。这是将被审查的代码,不幸的是,我不得不向没有经验的人逐行解释,所以这可能是我能找到的最佳解决方案。【参考方案3】:你可以这样做。因为Strings
是不可变的,所以在这里使用clone()
是安全的。感谢@iota 推荐setAll
int n = 10;
String[][] arr = new String[n][n];
Arrays.fill(arr[0], "0");
Arrays.setAll(arr, i->arr[0].clone());
for(String[] a : arr)
System.out.println(Arrays.toString(a));
打印
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
【讨论】:
试试arr[1][2] = "2"
。该数组中恰好有两个实例String[10]
:第一个子数组(原始)和第二个子数组(克隆)重复直到结束(字符串是不可变的,(子)数组不是)
@WJS 你可以使用Arrays.setAll
来避免这个问题:String[] row = arr[0].clone();Arrays.setAll(arr, i -> row.clone());
@WJS 没问题。【参考方案4】:
以下是基于stream 的解决方案,该解决方案使用函数式样式而非迭代式样式:
return Stream.generate(() ->
Collections.nCopies(10, "0").toArray(String[]::new))
.limit(10)
.toArray(String[][]::new);
请注意,根据可读性等要求,可能会认为经典的迭代样式更可取。
说明
Collections.nCopies(10, "0")
创建一个包含 10 个 "0"
值的 List<String>
。使用Collection.toArray(IntFunction)
将其转换为String
数组。这需要一个IntFunction
,它会生成一个给定长度的数组。 String[]::new
是一个 constructor lambda,它实现了 IntFunction<String[]>
,创建了一个给定长度的数组。
Stream.generate
通过调用给定的Supplier
创建每个元素的无限流。在这种情况下,供应商创建了前面提到的 10 元素长列表,结果是 Stream<String[]>
。使用了生成器,而不是 Collections.nCopies
,因为 String[][]
中的每个 String[]
都需要是不同的对象。
无限流仅限于使用Stream.limit(10)
的十个元素。
最后,使用Stream.toArray(IntFunction)
将Stream<String[]>
收集到String[][]
中,其工作方式与已经描述的Collection.toArray
方法相同。
【讨论】:
【参考方案5】:这是 for 循环和手动创建一行单元格的混合体。
String[][] board = new String[10][];
for (int i = 0; i < 10; i++)
board[i] = new String[]"0","0","0","0","0","0","0","0","0","0";
【讨论】:
【参考方案6】:
String#repeat
从 11 开始
String[][] board = new String[10][];
Arrays.setAll
- 每行重复 0
十次并拆分为一个数组:
Arrays.setAll(board, i -> "0".repeat(10).split(""));
Arrays.fill
- 在这种情况下,结果是一样的:
Arrays.fill(board, "0".repeat(10).split(""));
输出:
Arrays.stream(board).map(Arrays::toString).forEach(System.out::println);
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
另见:How can I fill this 2D array with X characters?
【讨论】:
以上是关于创建初始重复数据的二维字符串数组的最有效方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
从 .txt 文件中读取未知大小的整数二维数组的最有效方法是啥?