我一直在为即将到来的Java考试而学习,而且我很难绕过2D阵列。我有基础知识,例如创建和初始化2D数组,但是当涉及插入,删除甚至排序时,我会感到非常困惑。我的教授花了整整10分钟来完成基础知识,但在我们的考试中,我们应该知道如何创建2D对象数组并通过插入,删除和排序数组中的对象来操纵数据。他让我们在考试中手工编写所有代码,因此不允许任何计算机协助完成此过程。我花了好几个小时在这里和其他网站上倾注了一些例子,但我仍然觉得我不太了解这些材料,以便手工编写我的所有代码并使其正确。
我的困惑主要源于通常用于通过2D数组移动的嵌套for
循环。我可以看到其他人如何做并复制它,但我仍然不理解为什么循环的工作方式。我确信我在这里属于少数,但无论出于什么原因,它背后的逻辑让我完全迷失了。
采取这个(尽管很差)的例子,我一直在努力帮助自己理解2D数组(以及其他考试材料)。假设您经营汽车经销商,并且您想订购汽车来填充您的库存。该程序以一个顶级abstract
课程开始,该课程描述了您一般销售的汽车(在我的案例中是奥迪)。经销商提供4种型号的奥迪,A4
,A6
,A8
和R8
。所有这些汽车(类)都从名为super
的{{1}}继承方法。然后我想创建一个2D阵列来存储汽车库存。这将在我定义的另一个类中使用,包括Audi
,search()
和delete()
的方法。我们称之为sort()
。经销商只能容纳每个型号中的3个,因此阵列类似于AudiDealership
。 A4将填充第一行Audi[4][3]
,A6填充subscript 0
等。如何设置subscript 1
循环以从正确的行插入/删除?我显然不希望A4插入一行应该容纳A6,依此类推。
同样,我可以整天盯着代码并复制它,但我想理解 为什么 / 循环如何工作做。如果这个话题看似微不足道或被打死,我道歉,但是在发布这篇文章之前我所做的所有阅读都让我感到困惑。这个网站上的很多人都是你自己的优秀老师,所以我觉得有人可以用我能理解的方式解释这个。我的教授在这方面没有任何帮助,所以我正在使用外部手段来试图解决问题。我非常感谢任何建议或解释提前:)
答案 0 :(得分:2)
有助于将2D数组视为包含其他数组的数组。例如Cars[0][5]
正在0处访问汽车数组,而实际汽车位于该阵列的第5位。 Cars[1][5]
将访问位置1处的第二个汽车阵列,并且汽车位于位于位置1的阵列的5处。此代码可能有助于您理解它:
public class TwoDArray {
public static void main(String[] args)
{
Cars[][] cars; // declaring my 2D array.
cars = new Cars[4][]; // making the x axis 4 cars wide.
// now we will step along the x axis and create a Cars array in each slot.
for ( int a = 0; a < cars.length; a++) // cars.length = how wide.
{
cars[a] = new Cars[3]; // creating a new Cars[] in each slot of our 2D Car array @ position a.
//cars[a] = new 1D Cars array in slot a, length of 3.
}
// Note that we could have also created our array like this.
// Cars[][] cars = new Cars[4][3];
for ( int x = 0; x < cars.length; x++) //stepping along the x axis. cars.length = how wide.
{ //every time we step thru x we will execute this next loop.
for ( int y = 0; y < cars[x].length; y++) // stepping along the y axis. cars[x].length = how long.
{ // this loop will cycle through the y axis each time we increment x
cars[x][y] = new Cars( 2014, "someAudi", x + " " + y ); // creating a new car(s) @ x,y position.
}
}
// now to just print them.
for ( int x = 0; x < cars.length; x++) //stepping along the x axis again.
{
for ( int y = 0; y < cars[x].length; y++) // stepping along the y axis.
{
System.out.println(cars[x][y].getYear() +
" " + cars[x][y].getModel() +
" " + cars[x][y].getName() +
" " + cars[x][y].getManufacturer()); // the super method.
}
}
//INSERTION.
// To insert into your array, you simply need to provide the coordinates to insert the new Car(s) object.
// This next line will insert a new Car into the array at position 1 and the number 2 element of that array.
cars[1][2] = new Cars( 2014, "someAudi", "My Favorite Car!");
System.out.println(); // Just adding a space between outputs.
for ( Cars[] c: cars) //extracting each Cars array and name it c from the 2D Cars array named cars.
{ //basically stepping along the x axis and getting each array stored in x.
for ( Cars car: c) // Now we are stepping along the y axis.
{ // We are getting each individual Cars object and naming it car
// from each Cars[] named c from our first loop.
System.out.println(car.getYear() +
" " + car.getModel() +
" " + car.getName() +
" " + car.getManufacturer()); // the super method.
}
}
// NOTE* if you wish to insert a new element and do not have extra capacity then you will need to
// create a larger array @ cars[x]. cars[x] = new Cars[newSize];.
// DELETION.
// To delete an element you can just simply overwrite it.
// such as:
cars[1][1] = new Cars( 2014, "someAudi", "new Audi"); // Essentially we deleted and inserted a new object
// at position [1][1].
// If you just want to completely remove the element then you will need to update the size of the array.
// You can define a new array to hold the values of the old array minus the element that should be deleted.
Cars[] newArray = new Cars[cars[2].length - 1]; // We will use the array stored in cars[2] for this example.
// we set the length to one less to completely get rid of the
// old element.
int deleteThisPosition = 1; // We will use this variable to store the position that will be deleted from
// the array stored in cars[2].
int newArrayPosition = 0; // We will use this to increment our position in the new array along with `a`
// in the next for loop.
for ( int a = 0; a < cars[2].length; a++)
{
if ( a == deleteThisPosition) // if it reaches this position we will advance `a` and exclude it from
a++; // our new array.
newArray[newArrayPosition] = cars[2][a]; // we will store the value @ position `a` from the array in cars[2]
// into our newArray @ position `newArrayPosition`.
newArrayPosition++; // incrementing our variable to stay parallel with the array in cars[2].
}
//Now we can just assign the newArray to cars[2]. You will notice that Car `2 1` is no longer present.
cars[2] = newArray;
System.out.println(); // Just adding a space between outputs.
for ( Cars[] c: cars)
{
for ( Cars car: c)
{
System.out.println(car.getYear() +
" " + car.getModel() +
" " + car.getName() +
" " + car.getManufacturer()); // the super method.
}
}
}
}
以下是您示例中的其他类。
奥迪课程:
public abstract class Audi {
public String getManufacturer() { return "Audi"; } // method from this super class.
}
汽车类:
public class Cars extends Audi{ //extending Audi.
private String model;
private String name;
private int year;
Cars(int year, String model, String name)
{
this.year = year;
this.model = model;
this.name = name;
}
public String getName() { return name; }
public String getModel() { return model; }
public int getYear() { return year; }
}
如果您运行代码,您会注意到汽车名称中的模式。
输出:
注意每辆车名称中的模式,即唯一列。它对应于我们如何逐步完成循环。我们从x开始,每个x我们循环y。 x + " " + y
是我们在上面的代码中为每辆车命名的方式。
编辑:
This可能有助于插入。
答案 1 :(得分:1)
让我举个例子:
StringBuilder output = new StringBuilder();
for (int i = 0; i < table.length; i++) {
for (int j = 0; j < table[i].length; j++) {
output.append(table[i][j]);
}
output.append("\n");
}
这将是循环通过二维数组的代码。
代码直接进入第一行。这是i值。 当你想循环遍历行的每一列时, 你需要知道要遍历它的行的长度。
所以你从第一行开始,然后直接到表[i] .length的结尾。 在第一行中,第一个长度是table [0] .length。 这个长度为3,因为每行有3列。
我们现在已经完成了第一行的循环,我们到了第二行。 通过进入第二行,我增加1。 所以我们的指针现在显示在第2行(表[i] .length中的 i 现在为1,因为它总是从0开始),依此类推。
我们的指针遍历每一行,这就是它的工作原理。 对于每一个新行, i 的指针增加1(在for循环中为 i ++ )。
一行中的每个新列 j 增加, i 保持不变。 i 仅在您输入新行时发生变化。 j 通过输入新列进行更改。
希望这会有所帮助;)
编辑:
另一个例子:
如果您想获得第4行中第3列的值:
您想要的价值在这里:table[3][2];
记住数组总是从0开始计数。)
答案 2 :(得分:1)
Audi[4][3] cars = ... // your 2D array of all cars
正如您正确指定的那样,
A4将填充第一行,下标0,A6填充下标1,等等。
转换为cars[0]
持有Audi[] with A4 instances
,cars[1]
持有Audi[] with A6 instances
等。
好的,所以
Audi[] A4s = cars[0];
Audi[] A6s = cars[1];
...
然后你可以这么说
Audi A4_1 = A4s[0];
Audi A4_2 = A4s[1];
Audi A4_3 = A4s[2];
...
并为每辆车重复一遍。但这是一种错误的做法。首先,我们概括了对每辆车的访问。
如果你想遍历每个模型数组中的特定汽车,你需要有一个带有索引的for循环,比如说specificCarIndex
。遍历A4s
数组的循环很简单:
for (int specificCarIndex = 0; specificCarIndex < 3; specificCarIndex++) {
// Here A4s[specificCarIndex] contains an object of concrete Audi car of model A4
}
要遍历另一个模型的数组(如A6),您也会这样做,将A4s
替换为A6s
,依此类推。
现在我们需要概括一切。
for (int carModelIndex = 0; carModelIndex < 4; carModelIndex++) {
// Here cars[carModelIndex] holds an array of specific Audi model as you mentioned before
}
cars[carModelIndex]
基本上是Audi[] A4s
carModelIndex == 0
,Audi[] A6s
carModelIndex == 1
,依此类推。
既然我们知道如何访问每个奥迪模型的阵列,并且我们知道如何访问每个模型阵列中的单个车辆,我们将两者结合起来:
for (int carModelIndex = 0; carModelIndex < 4; carModelIndex++) {
for (int specificCarIndex = 0; specificCarIndex < 3; specificCarIndex++) {
// Here cars[carModelIndex][specificCarIndex] holds an object of type Audi which refers to a specific car
// If double index seems difficult, consider this:
// Audi[] audis = cars[carModelIndex] (array like A4s, A6s...)
// Audi audi = audis[specificCarIndex] (specific car)
// Just as in the examples before for-loops.
}
}