ループを使用せずにJavaで多次元配列を埋めるにはどうすればよいですか?
double[][] arr = new double[20][4];
Arrays.fill(arr, 0);
これにより、Java.lang.ArrayStoreException: Java.lang.Double
前もって感謝します!
これは、double[][]
はdouble[]
の配列であり、0.0
を割り当てることができないためです(double[] vector = 0.0
を実行するようなものです)。実際、Javaには真の多次元配列はありません。
それが起こると、Javaでは0.0
はdoubleのデフォルト値です。したがって、new
から取得すると、実際にはマトリックスはすでにゼロで埋められています。ただし、たとえば1.0
で埋めたい場合は、次のことができます。
APIがループを使用せずにこれを解決する方法を提供するとは思わない。ただし、for-eachループを使用してこれを行うのは非常に簡単です。
double[][] matrix = new double[20][4];
// Fill each row with 1.0
for (double[] row: matrix)
Arrays.fill(row, 1.0);
double[][] arr = new double[20][4];
Arrays.fill(arr[0], 0);
Arrays.fill(arr[1], 0);
Arrays.fill(arr[2], 0);
Arrays.fill(arr[3], 0);
Arrays.fill(arr[4], 0);
Arrays.fill(arr[5], 0);
Arrays.fill(arr[6], 0);
Arrays.fill(arr[7], 0);
Arrays.fill(arr[8], 0);
Arrays.fill(arr[9], 0);
Arrays.fill(arr[10], 0);
Arrays.fill(arr[11], 0);
Arrays.fill(arr[12], 0);
Arrays.fill(arr[13], 0);
Arrays.fill(arr[14], 0);
Arrays.fill(arr[15], 0);
Arrays.fill(arr[16], 0);
Arrays.fill(arr[17], 0);
Arrays.fill(arr[18], 0);
Arrays.fill(arr[19], 0);
OPはこの問題を解決する方法を尋ねましたループなし!なんらかの理由で、最近ではループを避けることが流行しています。どうしてこれなの?おそらく、map
、reduce
、filter
、および友人、およびeach
のようなメソッドを使用すると、ループを非表示にしてプログラムの冗長性を削減し、一種のクールな処理を実現できます。同じことが本当に素晴らしいUnixパイプラインにも当てはまります。またはjQueryコード。ループなしで見栄えが良くなります。
しかし、Javaにはmap
メソッドがありますか?実際にはありませんが、Function
またはeval
を持つexec
インターフェイスで定義できます。方法は難しくありませんし、良い練習になるでしょう。
これを行う別の方法ループなしは、末尾再帰を使用することです。はい、それは一種のばかげたものであり、誰も実際にそれを使用することはありませんが、おそらく、この場合はループが正常であることを示しています。それにもかかわらず、「まだ別のループフリーの例」を示して、楽しむために、ここにあります:
import Java.util.Arrays;
public class FillExample {
private static void fillRowsWithZeros(double[][] a, int rows, int cols) {
if (rows >= 0) {
double[] row = new double[cols];
Arrays.fill(row, 0.0);
a[rows] = row;
fillRowsWithZeros(a, rows - 1, cols);
}
}
public static void main(String[] args) {
double[][] arr = new double[20][4];
fillRowsWithZeros(arr, arr.length - 1, arr[0].length);
System.out.println(Arrays.deepToString(arr));
}
}
きれいではありませんが、OPの質問への回答には、explicitループはありません。
Per Java 8のように、この方法を使用できます。
double[][] arr = new double[20][4]; Arrays.stream(arr).forEach(a -> Arrays.fill(a, 0));
多次元配列の値をより適切にスマートに初期化できます。
ループを使用せずにJavaで多次元配列を埋めるにはどうすればよいですか?
多次元配列は単なる配列の配列であり、fill(...)
は配列の型と渡した値をチェックしません(この責任は開発者にあります)。
したがって、ループを使用せずに多次元配列を適切に埋めることはできません。
CやC++のような言語とは異なり、Java配列はオブジェクトであり、多次元配列では最後のレベルを除くすべてが他のArray
オブジェクトへの参照を含むことに注意してください。これについて100%確信はありませんが、ほとんどの場合、メモリに分散されているため、C/C++でできるように、ループなしで連続ブロックを埋めることはできません。
答えの拡張として、私はこの投稿を見つけましたが、4次元配列を埋めようとしていました。元の例は2次元配列のみですが、質問は「多次元」です。これに関する新しい質問を投稿したくありませんでした...
同じ方法を使用できますが、それらをネストして、最終的に1次元配列に到達する必要があります。
fourDArray = new float[10][10][10][1];
// Fill each row with null
for (float[][][] row: fourDArray)
{
for (float[][] innerRow: row)
{
for (float[] innerInnerRow: innerRow)
{
Arrays.fill(innerInnerRow, -1000);
}
}
};
私たち全員が時々そこにいたことを願ってはいけない<T>void Java.util.Arrays.deepFill(T[]…multiDimensional)
。問題が始まる
_Object threeByThree[][] = new Object[3][3];
_
_threeByThree[1] = null;
_および
_threeByThree[2][1] = new int[]{42};
_は完全に合法です。
(_Object twoDim[]final[]
_のみが正当であり、明確に定義されている場合...)
(以下のパブリックメソッドのいずれかを使用すると、呼び出し元のソースコードからループが保持されます。
ループをまったく使用しない場合は、ループを使用し、再帰を使用してArrays.fill()
(!)を呼び出します。)
_/** Fills matrix {@code m} with {@code value}.
* @return {@code m}'s dimensionality.
* @throws Java.lang.ArrayStoreException if the component type
* of a subarray of non-zero length at the bottom level
* doesn't agree with {@code value}'s type. */
public static <T>int deepFill(Object[] m, T value) {
Class<?> components;
if (null == m ||
null == (components = m.getClass().getComponentType()))
return 0;
int dim = 0;
do
dim++;
while (null != (components = components.getComponentType()));
filler((Object[][])m, value, dim);
return dim;
}
/** Fills matrix {@code m} with {@code value}.
* @throws Java.lang.ArrayStoreException if the component type
* of a subarray of non-zero length at level {@code dimensions}
* doesn't agree with {@code value}'s type. */
public static <T>void fill(Object[] m, T value, int dimensions) {
if (null != m)
filler(m, value, dimensions);
}
static <T>void filler(Object[] m, T value, int toGo) {
if (--toGo <= 0)
Java.util.Arrays.fill(m, value);
else
for (Object[] subArray : (Object[][])m)
if (null != subArray)
filler(subArray, value, toGo);
}
_
Java 8を使用すると、次のように(明示的な)ループを使用せずに2次元配列を宣言および初期化できます。
int x = 20; // first dimension
int y = 4; // second dimension
double[][] a = IntStream.range(0, x)
.mapToObj(i -> new double[y])
.toArray(i -> new double[x][]);
これにより、デフォルト値(0.0
の場合はdouble
)。
使用する塗りつぶし値を明示的に定義する場合は、DoubleStream
を追加できます。
int x = 20; // first dimension
int y = 4; // second dimension
double v = 5.0; // fill value
double[][] a = IntStream
.range(0, x)
.mapToObj(i -> DoubleStream.generate(() -> v).limit(y).toArray())
.toArray(i -> new double[x][]);
public static Object[] fillArray(Object[] arr,Object item){
Arrays.fill(arr, item);
return arr;
}
Character[][] maze = new Character[10][10];
fillArray(maze, fillArray(maze[0], '?'));
for(int i = 0;i<10;i++){
System.out.println();
for(int j = 0;j<10;j++){
System.out.print(maze[i][j]);
}
}
これがうまくいくことを願っています
簡単な言葉でJavaこのようなAPIを提供しない。ループを反復処理する必要があり、fillメソッドを使用して2D配列を1つのループで埋めることができる。
int row = 5;
int col = 6;
int cache[][]=new int[row][col];
for(int i=0;i<=row;i++){
Arrays.fill(cache[i]);
}