我在采访中被问到:"如何在不使用ArrayList,vector等任何集合的情况下创建动态数组。"
我说这是不可能的,因为数组是固定大小的。他们说你不可能写一个程序来回答这个问题。
我无法回答这个问题。他们给了我一个提示"使用泛型",尽管我似乎很难回答这个问题。任何人都可以帮助我吗?
答案 0 :(得分:4)
Collections的实现使用类似的概念。您需要使用default_size定义一个通用数组,例如n = 10(比如说),默认load_factor = 0.75(比如说)
T[] array = (T[])new Object[DEFAULT_SIZE];
变量index
用于存储数组中的当前位置。
当index > n*load_factor
创建更大尺寸的新数组并将所有元素复制到其中时它将是您的新数组,类似于删除元素index < n*load_factor
时(这些标准取决于许多参数,这只是示例)减小数组的大小。
部分示例代码
public class CustomArrayList <T> {
private int index = 0;
private final int DEFAULT_SIZE = 10;
private final double DEFAULT_LOAD = 0.75;
private T[] array;
public CustomArrayList(){
array = (T[])new Object[DEFAULT_SIZE];
}
public void add(T elem){
if(index>=array.length*DEFAULT_LOAD){
array = Arrays.copyOf(array, array.length+10);
}
array[index++]=elem;
}
}
答案 1 :(得分:0)
Java中的动态数组是什么?这是一个概念性的例子:
我们想将数据存储在一个数组中,但我们不知道它有多大。因此,当我们想要插入并且没有空间时,我们需要找到更大的内存块并复制该块中的所有条目。现在考虑两种方法。
糟糕的方式
我们分配了1000个条目的块。
每次没有足够的空间时,我们会分配一个包含100多个条目的新块。
需要多长时间:
要插入n个条目,副本数将为1000
×
ķ
+ 100
×
(1 + 2 +
。 。 。
+(
ķ
-
1))= 1000 k + 50k(k-1)
因此,所花费的时间在k中也是二次的,并且在n中也是如此
好方法
分配1000个条目的块,当没有足够的空间时,分配一个大小为两倍的新块。
需要多长时间
总份数为:1000
×
(1 + 2 + 4 +
...
+ 2 ^(
ķ
-
1)
)= 1000
×
(2 ^ķ
-
1)
&LT =
ñ
插入总数为:1000
×
(1 + 1 + 2 + 4 +
...
+ 2 ^(
ķ
-
1)
)= 1000
×
2 ^ K = N
所以n的总时间是线性的,平均时间是恒定的
一旦理解了这个概念,您就可以用你知道的任何语言创建一个动态数组。
答案 2 :(得分:0)
我对你的问题有所了解。动态数组是在运行时改变它的大小的东西。我刚刚完成了十二年级,我正在分享我的想法......
计划:
public class DynamicArr {//method to increase size dynamically during runtime
public static int[] incrSize(int arr[]) {
int len = arr.length;
int newArr[] = new int[len+1]; //increasing the length of the current array in an other temporary array
return newArr; // returning the new array
}
public static void main(String... strings) {
int a[] = new int[10];
System.out.println("Size Before Increase: " + a.length);
a = incrSize(a); // pointing the reference to the new array by calling the incrSize() method
System.out.println("Size After Increase: " + a.length);
}
}
您可以将当前数组中的所有值复制到临时数组中,并将新值添加到可以扩展数组大小的数组中。 您还可以根据需要扩展大小。
希望这会有所帮助......
答案 3 :(得分:0)
他们基本上想要了解一些事情。就像你如何为这样一个阵列建模“持有人”一样,你将如何公开get(int index)
或set(T value, int index)
或size
。
“使用泛型”是一个非常好的提示,因为你应该至少开始:
Holder<T> {
T[] array = (T[])new Object[10]; // 10 just as an example
}
如果你写下来,他们可能会进一步询问为什么不T[] array = new T[10]
你应该说你不能在java中创建一个通用数组(你甚至可以在这里提到@SafeVarArgs
) 。再往下说你应该说数组是协变的,并且允许转换为数组,但不是集合;它也会生成一个编译器警告,你需要压制。
稍后您可以添加一个方法,例如add(T value)
以及如何实现该方法。在这里,他们希望你知道什么
Arrays.copyOfRange
或System.arrayCopy
是以及如何运作。
他们甚至可能会问为什么不添加 T
的所有子类型及其正确的语法(look for generics bounds
)。
您还可能需要考虑元素的delete
如何对特定索引起作用?你会null
吗?你会删除吗?如果是这样,你会如何从阵列中做到这一点?什么东西被删除后你会缩小数组的大小吗? (提示:java集合不会这样做,除非你明确告诉他们:ArrayList#trimToSize()
)
当你的内部数组已满,并且你想再添加一个元素时,你会扩展它多少? 50%
,75%
?或者只是单个元素的足够空间?如果你知道jdk的内部集合是如何工作的,答案就会非常简单。
我想这对所有IMO来说都不是一个糟糕的面试问题。