Java - 编程基础:Java中的数据结构(2)
2007-06-06 21:35
543 查看
程序运行正常,好像没有出现任何问题。程序也确实真的不会出现问题,因为其逻辑如此简单,不会但来问题。但是这个程序性能是最优的吗?
让我们来看看 ArrayList 类的实现 :
public class ArrayList extends AbstractList implements List, RandomAccess,
Cloneable, java.io.Serializable
{
……
private transient Object elementData[];
……
public ArrayList(int initialCapacity)
{
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "
+ initialCapacity);
this.elementData = new Object[initialCapacity];
}
public ArrayList()
{
this(10);
}
……
public void ensureCapacity(int minCapacity)
{
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity)
{
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3) / 2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
elementData = new Object[newCapacity];
System.arraycopy(oldData, 0, elementData, 0, size);
}
}
public boolean add(Object o)
{
ensureCapacity(size + 1);
elementData[size++] = o;
return true;
}
}
正如其名字所暗示的, ArrayList 内部是使用数组保存的数据, Java 中的数组是固定大小的,要想改变数组的大小,就要重新开辟一个新的大小的内存区域,把原先的数据复制到新内存区域中,这就是增量性数组。由于需要重新开辟内存区域并进行数据的复制,因此改变数组的大小是非常耗时的,我们要尽量避免改变数组的大小。
从 ArrayList 的内部实现我们可以发现, ArrayList 中储存数据用的数组的默认大小为 10 ,当调用 add 方法向其中增加数据的时候,如果数据已经超过了数组的大小, ArrayList 就要增加数组的大小以便容纳更多的数据。在我们的这个人例子中,由于数据已经超过 10 条,当增加到第 11 条的时候, ArrayList 就会进行一次“扩容”,这是一个非常耗时的操作,因此我们必须想方设法避免。
我们注意到 ArrayList 有一个带参数的构造函数: public ArrayList(int initialCapacity) ,这里的 initialCapacity 代表构造此 ArrayList 的时候,数组的大小。我们可以使用此构造函数来避免“扩容”。
实现代码 2 :
PersonInfo[] persons = new PersonInfo[] {
new PersonInfo("00001", "Tom", 20),
new PersonInfo("00002", "Tim", 23),
new PersonInfo("00003", "Sally", 26),
new PersonInfo("00005", "Lily", 20),
new PersonInfo("00006", "Lucy", 30),
new PersonInfo("00008", "Kitty", 20),
new PersonInfo("00011", "Smith", 20),
new PersonInfo("00031", "Ketty", 22),
new PersonInfo("00051", "Melly", 20),
new PersonInfo("00022", "Blues", 20),
new PersonInfo("00033", "Tid", 18),
new PersonInfo("00101", "Duoliaos", 30),
new PersonInfo("00201", "Yang", 26),
new PersonInfo("03001", "King", 20),
new PersonInfo("05001", "Lee", 20),
new PersonInfo("10001", "Wang", 20),
new PersonInfo("06001", "Pizza", 60) };
List list = new ArrayList(persons.length);
for (int i = 0, n = persons.length; i < n; i++)
{
PersonInfo pInfo = persons[i];
list.add(pInfo.getId());
}
我们已经知道了 list 将放置 persons.length 条数据,因此我们就使 list 中数组的默认大小设置为 persons.length ,这样系统的性能就好了很多。
不仅是 ArrayList ,我们在使用 Vector 、 HashMap 等类的同时,同样要注意这个问题。
让我们来看看 ArrayList 类的实现 :
public class ArrayList extends AbstractList implements List, RandomAccess,
Cloneable, java.io.Serializable
{
……
private transient Object elementData[];
……
public ArrayList(int initialCapacity)
{
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "
+ initialCapacity);
this.elementData = new Object[initialCapacity];
}
public ArrayList()
{
this(10);
}
……
public void ensureCapacity(int minCapacity)
{
modCount++;
int oldCapacity = elementData.length;
if (minCapacity > oldCapacity)
{
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3) / 2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
elementData = new Object[newCapacity];
System.arraycopy(oldData, 0, elementData, 0, size);
}
}
public boolean add(Object o)
{
ensureCapacity(size + 1);
elementData[size++] = o;
return true;
}
}
正如其名字所暗示的, ArrayList 内部是使用数组保存的数据, Java 中的数组是固定大小的,要想改变数组的大小,就要重新开辟一个新的大小的内存区域,把原先的数据复制到新内存区域中,这就是增量性数组。由于需要重新开辟内存区域并进行数据的复制,因此改变数组的大小是非常耗时的,我们要尽量避免改变数组的大小。
从 ArrayList 的内部实现我们可以发现, ArrayList 中储存数据用的数组的默认大小为 10 ,当调用 add 方法向其中增加数据的时候,如果数据已经超过了数组的大小, ArrayList 就要增加数组的大小以便容纳更多的数据。在我们的这个人例子中,由于数据已经超过 10 条,当增加到第 11 条的时候, ArrayList 就会进行一次“扩容”,这是一个非常耗时的操作,因此我们必须想方设法避免。
我们注意到 ArrayList 有一个带参数的构造函数: public ArrayList(int initialCapacity) ,这里的 initialCapacity 代表构造此 ArrayList 的时候,数组的大小。我们可以使用此构造函数来避免“扩容”。
实现代码 2 :
PersonInfo[] persons = new PersonInfo[] {
new PersonInfo("00001", "Tom", 20),
new PersonInfo("00002", "Tim", 23),
new PersonInfo("00003", "Sally", 26),
new PersonInfo("00005", "Lily", 20),
new PersonInfo("00006", "Lucy", 30),
new PersonInfo("00008", "Kitty", 20),
new PersonInfo("00011", "Smith", 20),
new PersonInfo("00031", "Ketty", 22),
new PersonInfo("00051", "Melly", 20),
new PersonInfo("00022", "Blues", 20),
new PersonInfo("00033", "Tid", 18),
new PersonInfo("00101", "Duoliaos", 30),
new PersonInfo("00201", "Yang", 26),
new PersonInfo("03001", "King", 20),
new PersonInfo("05001", "Lee", 20),
new PersonInfo("10001", "Wang", 20),
new PersonInfo("06001", "Pizza", 60) };
List list = new ArrayList(persons.length);
for (int i = 0, n = persons.length; i < n; i++)
{
PersonInfo pInfo = persons[i];
list.add(pInfo.getId());
}
我们已经知道了 list 将放置 persons.length 条数据,因此我们就使 list 中数组的默认大小设置为 persons.length ,这样系统的性能就好了很多。
不仅是 ArrayList ,我们在使用 Vector 、 HashMap 等类的同时,同样要注意这个问题。
相关文章推荐
- Java - 编程基础:Java中的数据结构(1)
- Java - 编程基础:Java中的数据结构(2)
- 编程基础:Java中的数据结构
- java基础------数据结构---》冒泡排序
- java 编程思想——基础篇
- Java网络编程基础 InetAddress类的使用
- Java基础---网络编程 (黑马程序员)
- Java基础课程学习总结,使用LinkedList简单模拟队列数据结构和堆栈数据结构的实现
- 跟着姜少学Java基础编程之九:数组
- 第2章 Java编程基础——FAQ2.07 final关键字有什么含义?具体如何应用?
- 第2章 Java编程基础——FAQ2.15 Java中有哪些运算符?优先级如何?
- 第2章 Java编程基础——FAQ2.23 break和continue语句有什么区别?
- Java基础之网络编程(一)
- java基础知识---网络编程、反射技术、正则表达式
- Java基础---网络编程
- Java基础知识-网络编程
- 【Java基础之网络编程】代码库(七)
- Java基础编程6,循环语句
- 黑马程序员-----java编程基础
- 黑马程序员—Java基础—java基础语法:数据结构,运算符,选择结构,循环结构