- 浏览: 400941 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
di1984HIT:
学习了,学习了~
Jpcap 网络抓包工具 -
Allen_J_Will:
pengtyao 写道Allen_J_Will 写道为何按照楼 ...
使用mod_cluster进行负载均衡初步预研 -
pengtyao:
Allen_J_Will 写道为何按照楼主的步骤,并参考了 h ...
使用mod_cluster进行负载均衡初步预研 -
Allen_J_Will:
为何按照楼主的步骤,并参考了 http://docs.jbos ...
使用mod_cluster进行负载均衡初步预研 -
362980633:
我在项目中写context.xml,项目没有不部署在tomca ...
配置Tomcat的<Context>元素
java.lang.System下的arraycopy和java.util.Arrays.copyOf方法
(1) java.lang.System.arraycopy
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
问题:方法没有任何的实现,具体是如何实现的呢?
以下是关于该方法具体的说明:
由上述的源码不难看出两者的最大区别是:
arraycopy 方法会因为新数组大小比久数组大小小而报IndexOutOfBoundsException
copyOf 则不会因此报错,因为copyOf 的返回值是在内部new 好的copy 数组,而该copy 数组new 的大小就等于newLength ,
故即使在客户端指定好了新数组newArray 的大小,接收到返回值后也是指向底层new 出来的数组copy 。换句话说( 也可以因此推出其他的区别) ,在客户端代码中即使不给新数组new 对象,如:String[] newStr = null;
那么对于arraycopy 是会报NullPointerException 的错误的,而对于java.util.Arrays 中的copyOf 方法则由于jdk 底层
已经new 出了对象而不会报该错误!不过需要特别注意的是:copyOf 方法最后也是调用System.arraycopy 的方法,不过由于前面的准备,异常情况就不会出现了。
下面是一个具体实例:
与此同时,java.util.Arrays 还重载了很多copyOf 方法:
等等;
现在再来讨论下ArrayList 中对该两个方法的使用情况:
由于ArrayList 底层是用数组实现的,那么就必然会面临两个问题:
(1) 一开始必须要指定一个初始化的数组大小;
java.util.ArrayList 中初始化ArrayList 大小是10 :
可见,每次添加元素时,JDK 都会先检查数组elementData 的容量是否已经满了,如果满了,就会调用Arrays.copyOf 方法,用elementData 中的元素和新数组的长度构造一个新的数组,并重新赋值给elementData 数组。此处不难看出,由于需求是把长度已经增长了的elementData 数组重新赋值给elementData ,故直接使用System.arraycopy 方法是不适合的。
另外,新数组长度的改变也是有讲究的,JDK 的设计是每次有新的扩展数组长度的需要到来时,就按int newCapacity = (oldCapacity * 3)/2 + 1; 的算法构造新数组的长度,不难看出,这种算法构造出来的新的数组长度的增量都会比上一次大( 而且是越来越大) ,即认为客户需要增加的数据很多,而避免频繁newInstance 的情况。
下面再来看ArrayList 中的toArray 方法
此处主要看第二个toArray 方法,可见,客户是想把ArrayList 中的元素转换成数组并存放到指定的a 数组中,因此就要判断a.length 与elementData 当前的大小了,如果a.length<size, 那么调用System.arraycopy 方法是肯定会报错的,故必须调用Arrays.copyOf 方法,而如果a.length>=size 那么就比不上调用System.arraycopy 方法来得方便了( 因为根据上面说的,Arrays.copyOf 方法最终也是调用System.arraycopy 方法的) 。
综上所述,可以总结:在允许的情况下,尽量调用System.arraycopy 方法,实在不行再调用Arrays.copyOf 方法。
From:http://blog.csdn.net/javaclan/archive/2011/04/29/6372176.aspx
Simple Stack push method
如果不采用动态数组策略,将会抛:
(1) java.lang.System.arraycopy
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
问题:方法没有任何的实现,具体是如何实现的呢?
以下是关于该方法具体的说明:
* @param src the source array. * @param srcPos starting position in the source array. * @param dest the destination array. * @param destPos starting position in the destination data. * @param length the number of array elements to be copied. * @exception IndexOutOfBoundsException if copying would cause * access of data outside array bounds. * @exception ArrayStoreException if an element in the <code>src</code> * array could not be stored into the <code>dest</code> array * because of a type mismatch. * @exception NullPointerException if either <code>src</code> or * <code>dest</code> is <code>null</code>. [b](2) java.util.Arrays.copyOf [/b] public static <T> T[] copyOf(T[] original, int newLength) { return (T[]) copyOf(original, newLength, original.getClass()); } public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) { T[] copy = ((Object)newType == (Object)Object[].class) ? (T[]) new Object[newLength] : (T[]) Array.newInstance(newType.getComponentType(), newLength); System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; }
由上述的源码不难看出两者的最大区别是:
arraycopy 方法会因为新数组大小比久数组大小小而报IndexOutOfBoundsException
copyOf 则不会因此报错,因为copyOf 的返回值是在内部new 好的copy 数组,而该copy 数组new 的大小就等于newLength ,
故即使在客户端指定好了新数组newArray 的大小,接收到返回值后也是指向底层new 出来的数组copy 。换句话说( 也可以因此推出其他的区别) ,在客户端代码中即使不给新数组new 对象,如:String[] newStr = null;
那么对于arraycopy 是会报NullPointerException 的错误的,而对于java.util.Arrays 中的copyOf 方法则由于jdk 底层
已经new 出了对象而不会报该错误!不过需要特别注意的是:copyOf 方法最后也是调用System.arraycopy 的方法,不过由于前面的准备,异常情况就不会出现了。
下面是一个具体实例:
package com.yilong.array.copyof; public class ArrayCopyOf { public static void main(String[] args) { String[] oldStr = new String[6]; setValues(oldStr); String[] newStr = null; newStr = java.util.Arrays.copyOf(oldStr, 6); //System.arraycopy(oldStr, 0, newStr, 0, oldStr.length); // 会报错NullPointerException ,如果改为newStr = new String[5], // 那么调用Arrays.copyOf 方法不会报错,而调用System.arraycopy 方法 // 则回报IndexOutOfBoundsException print(oldStr); print(newStr); System.out.println(oldStr.length); System.out.println(newStr.length); } private static void print(String[] newStr) { // TODO Auto-generated method stub for (int i = 0; i < newStr.length; i++) { System.out.print(newStr[i] + " : "); } System.out.println(); } private static void setValues(String[] oldStr) { // TODO Auto-gemmnerated method stub for (int i = 0; i < oldStr.length; i++) { oldStr[i] = "str " + i; } } }
与此同时,java.util.Arrays 还重载了很多copyOf 方法:
public static byte[] copyOf(byte[] original, int newLength) { byte[] copy = new byte[newLength]; System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; } public static int[] copyOf(int[] original, int newLength) { int[] copy = new int[newLength]; System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; }
等等;
现在再来讨论下ArrayList 中对该两个方法的使用情况:
由于ArrayList 底层是用数组实现的,那么就必然会面临两个问题:
(1) 一开始必须要指定一个初始化的数组大小;
java.util.ArrayList 中初始化ArrayList 大小是10 :
private transient Object[] elementData;// 为什么要设置成transient? 不想被序列化? public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity); this.elementData = new Object[initialCapacity]; } public ArrayList() { this(10); } (2) 当数组容量不够时,能够动态增加容量。 java.util.ArrayList 中的add(E e) 方法 public boolean add(E e) { ensureCapacity(size + 1); // Increments modCount!! elementData[size++] = e; return true; } 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; // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } }
可见,每次添加元素时,JDK 都会先检查数组elementData 的容量是否已经满了,如果满了,就会调用Arrays.copyOf 方法,用elementData 中的元素和新数组的长度构造一个新的数组,并重新赋值给elementData 数组。此处不难看出,由于需求是把长度已经增长了的elementData 数组重新赋值给elementData ,故直接使用System.arraycopy 方法是不适合的。
另外,新数组长度的改变也是有讲究的,JDK 的设计是每次有新的扩展数组长度的需要到来时,就按int newCapacity = (oldCapacity * 3)/2 + 1; 的算法构造新数组的长度,不难看出,这种算法构造出来的新的数组长度的增量都会比上一次大( 而且是越来越大) ,即认为客户需要增加的数据很多,而避免频繁newInstance 的情况。
下面再来看ArrayList 中的toArray 方法
public Object[] toArray() { return Arrays.copyOf(elementData, size); } public <T> T[] toArray(T[] a) { if (a.length < size) // Make a new array of a's runtime type, but my contents: return (T[]) Arrays.copyOf(elementData, size, a.getClass()); System.arraycopy(elementData, 0, a, 0, size); if (a.length > size) a[size] = null; return a; }
此处主要看第二个toArray 方法,可见,客户是想把ArrayList 中的元素转换成数组并存放到指定的a 数组中,因此就要判断a.length 与elementData 当前的大小了,如果a.length<size, 那么调用System.arraycopy 方法是肯定会报错的,故必须调用Arrays.copyOf 方法,而如果a.length>=size 那么就比不上调用System.arraycopy 方法来得方便了( 因为根据上面说的,Arrays.copyOf 方法最终也是调用System.arraycopy 方法的) 。
综上所述,可以总结:在允许的情况下,尽量调用System.arraycopy 方法,实在不行再调用Arrays.copyOf 方法。
From:http://blog.csdn.net/javaclan/archive/2011/04/29/6372176.aspx
Simple Stack push method
private String[] buffer = new String[100]; public final void push(String goods) { if (point + 2 > buffer.length) { // System.arraycopy is better than Arrays.copyOf // buffer = Arrays.copyOf(buffer, buffer.length + INCREMENT); String[] newBuffer = new String[(buffer.length * 3) / 2 + 1]; System.arraycopy(buffer, 0, newBuffer, 0, buffer.length); buffer = newBuffer; } point++; buffer[point] = goods; System.out.println("buffer size ========================" + buffer.length); System.out.println("point ========================" + point); }
如果不采用动态数组策略,将会抛:
Exception in thread "****producer***" java.lang.ArrayIndexOutOfBoundsException: 100
发表评论
-
通过JUnit理解反射与注解的使用方式与场景
2014-04-07 22:20 1616通过JUnit深入理解反射与注 解的使用方式与场景 引用 ... -
SiteMesh----Web界面布局、装饰框架
2013-06-02 22:48 1777一、SiteMesh项目简介 ... -
DWR--远程服务器端Ajax开源框架
2013-03-17 22:04 1376简介 DWR(Direct Web Remoting)是一个用 ... -
Jpcap 网络抓包工具
2012-07-22 15:17 145451.jpcap说明与安装 JAVA语言虽然在TCP/U ... -
初识敏捷开发
2011-12-27 23:50 1034敏捷软件开发宣言 个体 ... -
XStream序列化与反序列化对象
2011-12-25 19:50 6485XStream是一个将java对象序列化为xml以及从xml反 ... -
持续集成(Continous Integration)
2011-12-14 23:46 1282对持续集成的理解: 1、持续集成是敏捷开发的一种重要实践; 2 ... -
ConcurrentHashMap原理分析
2011-06-09 15:05 4661集合是编程中最常用的数据结构。而谈到并发,几乎总是离不开集合这 ... -
开发知识整理----数组和集合框架(2011-06)
2011-06-07 17:36 1660一、数组 Java数组 ... -
开发知识整理----多线程(2011-05)
2011-05-29 23:21 1338一.多线程 1.进程与线 ... -
Java多线程设计模式:wait/notify机制
2011-05-20 00:32 1189引用内容摘要:如果条件不满足,则等待。当条件满足时,等待该条件 ... -
开发知识整理(2011-04)
2011-04-20 10:54 11331.对象的哪些属性与方法应该公开,哪些应该隐藏? 封装两大原则 ... -
近期开发能力加强与整理计划
2011-04-18 23:15 1171在这埋下的种子没有发芽... 也许真不适合... 不得已要换块 ... -
Junit设计模式学习
2011-04-12 23:05 1165Junit设计模式学习 -
instanceof VS isAssignableFrom
2011-04-06 00:49 1137public static void main(Str ... -
c:forEach标签的使用
2011-03-19 17:02 1143c:forEach标签的使用 在JSP的开发中,迭代是经常要 ... -
a4j:jsFunction & a4j:actionparam
2011-03-17 21:28 3744这次JSF的项目中遇到一种特殊情况,在一个CommandLin ... -
JSF f:loadBundle标签
2011-03-16 11:04 1562JSF f:loadBundle标签是JSF提供的一个支持JS ... -
cookie与session专题
2011-03-10 19:55 991一、cookie机制和session机 ... -
JVM 内存初学 (堆(heap)、栈(stack)和方法区(method) )
2010-12-14 00:09 1398JVM 内存初学 (堆(heap)、 ...
相关推荐
`System.arraycopy` 和 `Arrays.copyOf` 都是Java中用于复制数组的方法,但它们在使用和处理异常情况上有所不同。这两个方法在处理数组复制时,提供了便利和效率,但各有其适用场景。 `System.arraycopy` 是一个...
3. **Arrays.copyOf()**:Java 5引入的静态方法,可以方便地创建一个新数组并复制旧数组的内容。 ```java int[] original = {1, 2, 3}; int[] copy = Arrays.copyOf(original, original.length); ``` 数组的...
1. `java.lang`:这是所有Java程序默认导入的包,包含了基本数据类型、异常处理和系统相关的类,如`String`、`Integer`、`System`、`Exception`等。 2. `java.util`:提供了集合框架、日期时间、随机数、位集、队列...
Java提供了System.arraycopy()方法用于复制数组,Arrays类中的copyOf()和copyOfRange()方法则可以用来创建数组副本或部分数组副本。合并两个数组可以创建新数组,并逐个复制元素。 七、源代码实例 在这个详细教程中...
在C#中,我们可以使用`Buffer.BlockCopy()`方法来拼接`byte`数组,其基本用法与Java的`System.arraycopy()`类似。而在C++中,我们可能需要使用`std::copy`函数结合`std::vector`来实现相同的功能。 除了基本的数组...
此外,尽管示例中未提及,`System`类也包含了一些与数组操作相关的静态方法,例如`System.arraycopy()`,可用于高效地复制数组的一段区域。然而,`Arrays`类提供的方法通常更易于使用,功能更全面,尤其是在处理复杂...
- 自Java 5起,`java.util.Arrays`类提供了`copyOf()`方法,它也能用于复制数组。对于基本类型数组,这是与`System.arraycopy()`等价的,而对于对象数组,它同样执行浅拷贝。 ```java int[] original = {1, 2, 3,...
`java.util.Arrays.copyOf()` 方法是拷贝数组的一个简单而有效的方式。该方法可以创建一个新的数组,并将原始数组的所有元素复制到新数组中。 ```java char[] sourceArr = new char[1000]; char[] destineArr =...
java.util.Arrays类提供了更为方便的静态方法,如`Arrays.copyOf()`和`Arrays.concatenate()`,可以更直接地实现数组的合并,特别是对于多维数组,使用这些方法可以非常容易地完成合并任务。 Python数组合并: ...
文章目录1. 直接赋值2....(注:如果想打印数组内的所有值,可以使用Arrays.toString(x)方法,但需import java.util.Arrays) int[] originalArray = { 1, 2, 3, 4, 5 }; int[] newArray = originalArray
- `System.arraycopy()` 方法用于复制数组的一部分到另一个数组。它需要源数组、源起始位置、目标数组、目标起始位置和复制的元素数量。 - `Arrays.copyOf()` 是一个静态方法,可以创建一个新的数组,其内容是原...
Java提供了一些内置方法,如`length`,用于获取数组的长度,以及`System.arraycopy()`用于复制数组的一部分。 计算两个数组的并集主要有两种方法:一种是使用循环遍历两个数组,另一种是利用Java集合框架,如...
- **使用`Arrays.copyOf`**: `java.util.Arrays`类提供的方法,可以复制整个数组或数组的一部分到一个新的数组中。 #### 二、集合 **集合**是Java中用来存储和操作一组对象的容器。集合框架提供了多种不同类型的...
- 复制: `System.arraycopy(sourceArray, sourceStartIndex, destArray, destStartIndex, length);` ### 九、排序算法 - **冒泡排序**: - 原理: 通过比较相邻的元素并交换它们的位置来对数组进行排序。 - 实现...
` 使用 `Arrays.copyOf()` 方法将数组 `arr` 扩展一个元素的位置,并将原数组的所有元素复制到新数组中。 - **向数组末尾添加元素**:`arr[arr.length - 1] = max;` 将 `max` 值添加到数组 `arr` 的最后一个位置。 ...
在性能测试中,`System.arraycopy()`表现最优,其次是`clone()`方法,而`Arrays.copyOf()`和`Arrays.copyOfRange()`的效率相近,均优于for循环。在实际应用中,应根据具体需求选择合适的复制方法。
Arrays类是一个工具类,其中包含了数组操作的很多方法,比如搜索和排序。该类中的方法均为static修饰的,可以直接通过Arrays.xxx(xxx)的形式调用方法。 2. asList(T... a)方法 asList(T... a)方法是Arrays类中的一...
这里`System.arraycopy`的第一个参数是要复制的源数组,第二个参数是源数组的起始索引,第三个参数是目标数组,第四个参数是目标数组的起始索引,第五个参数是要复制的元素数量。 - **使用`Arrays.copyOf`方法**:...
数组复制可以通过`System.arraycopy()`方法或者`Arrays.copyOf()`方法实现。 #### 第六章:异常处理 - **异常处理机制** 异常处理是Java中一种重要的机制,用于处理程序运行时可能出现的错误。Java中的异常处理...
- 相比于传统的 `System.arraycopy` 方法,更加简洁明了且易于使用。 - 提高了代码的可读性和维护性。 以上就是Java 6 Collection Framework中新特性的详细介绍,这些新特性和改进极大地增强了Java集合框架的功能...