Java 为什么要在cc 继承类前加publicCounter

用户名:randy_shandong
文章数:243
评论数:70
访问量:228689
注册日期:
阅读量:1297
阅读量:3317
阅读量:458075
阅读量:1142746
51CTO推荐博文
1.jcmd1.1作用发送诊断命令请求到正在运行的Java虚拟机(JVM)。它必须和JVM运行在同一台机器上,并且与启动JVM用户具有相同的组权限。1.2语法jcmd&[-l|-h|-help]
jcmd&pid|main-class&PerfCounter.print
jcmd&pid|main-class&-f&filename
jcmd&pid|main-class&command[&arguments]Perfcounter.print:打印Java进程的性能计数器-f filename:从中读取诊断命令,每行命令必须在一行内写完command [arguments]:诊断指令1.3命令列表C:\Users\Administrator&jcmd&7048&help
The&following&commands&are&available:
VM.native_mercial_features
ManagementAgent.stop
ManagementAgent.start_local
ManagementAgent.start
Thread.print
GC.class_histogram
GC.heap_dump
GC.run_finalization
VM.system_mand_line
VM.version#打印JDK及版本
C:\Users\Administrator&jcmd&7048&VM.version
Java&HotSpot(TM)&64-Bit&Server&VM&version&24.75-b04
JDK&7.0_75
#打印虚拟机系统属性
可以有几百行的信息显示。
C:\Users\Administrator&jcmd&7048&&VM.system_properties
#Sat&Apr&15&21:24:31&CST&2017
java.runtime.name=Java(TM)&SE&Runtime&Environment
sun.boot.library.path=D\:\\Java\\jdk1.7.0_75\\jre\\bin
java.vm.version=24.75-b04
shared.loader=
java.vm.vendor=Oracle&Corporation
java.vendor.url=http\:///
path.separator=;
java.vm.name=Java&HotSpot(TM)&64-Bit&Server&VM
tomcat.util.buf.StringCache.byte.enabled=true
file.encoding.pkg=sun.io
#打印用于虚拟机的所有标志
即使没有设置,一些默认值将被打印出来
C:\Users\Administrator&jcmd&7048&VM.flags
-XX:InitialHeapSize=&-XX:MaxHeapSize=&-XX:+UseCompressedOops&
-XX:-UseLargePagesIndividualAllocation&-XX:+UseParallelGC
[Global&flags]
&&&&uintx&AdaptivePermSizeWeight&&&&&&&&&&&&&&&&&&&&=&20&&&&&&&&&&&&&&{product}&&&&&&&&&&&
&&&&uintx&AdaptiveSizeDecrementScaleFactor&&&&&&&&&&=&4&&&&&&&&&&&&&&&{product}&&&&&&&&&&&
&&&&uintx&AdaptiveSizeMajorGCDecayTimeScale&&&&&&&&&=&10&&&&&&&&&&&&&&{product}&&&&&&&&&&&
&&&&uintx&AdaptiveSizePausePolicy&&&&&&&&&&&&&&&&&&&=&0&&&&&&&&&&&&&&&{product}&&&&&&&&&&&
&&&&uintx&AdaptiveSizePolicyCollectionCostMargin&&&&=&50&&&&&&&&&&&&&&{product}&&&&&&&&&&&
&&&&uintx&AdaptiveSizePolicyInitializingSteps&&&&&&&=&20&&&&&&&&&&&&&&{product}&&&&&&&&&&&
&&&&uintx&AdaptiveSizePolicyOutputInterval&&&&&&&&&&=&0&&&&&&&&&&&&&&&{product}&&&&&&&&&&&
&&&&uintx&AdaptiveSizePolicyWeight&&&&&&&&&&&&&&&&&&=&10&&&&&&&&&&&&&&{product}&&&&&&&&&&&
&&&&uintx&AdaptiveSizeThroughPutPolicy&&&&&&&&&&&&&&=&0&&&&&&&&&&&&&&&{product}&&&&&&&&&&&
&&&&uintx&AdaptiveTimeWeight&&&&&&&&&&&&&&&&&&&&&&&&=&25&&&&&&&&&&&&&&{product}&&&&&&&&&&&
&&&&&bool&AdjustConcurrency&&&&&&&&&&&&&&&&&&&&&&&&&=&false&&&&&&&&&&&{product}&&&&&&&&&&&
&&&&&bool&AggressiveOpts&&&&&&&&&&&&&&&&&&&&&&&&&&&&=&false&&&&&&&&&&&{product}&&&&&&&&&&&
&&&&&intx&AliasLevel&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&=&3&&&&&&&&&&&&&&&{C2&product}&&&&&&&&
&&&&&bool&AlignVector&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&=&true&&&&&&&&&&&&{C2&product}&
&&&&&uintx&InitialHeapSize&&&&&&&&&&&&&&&&&&&&&&&&&&:=&&&&&&&&{product}&
&&&&&#冒号:表示非默认值&
&&&&&#打印(秒)正常运行时间
&&&&&C:\Users\Administrator&jcmd&7048&VM.uptime
&&&&&&&&7048:
&&&&&&&&&s&&
&#类直方图&&&&&&&
&C:\Users\Administrator&jcmd&7048&GC.class_histogram&&&&&12333.txt&&&&&&&
&num&&&&&#instances&&&&&&&&&#bytes&&class&name
----------------------------------------------
&&&1:&&&&&&&&&11678&&&&&&&&8137440&&[B
&&&2:&&&&&&&&&30213&&&&&&&&4300992&&[C
&&&3:&&&&&&&&&28188&&&&&&&&3966976&&&constMethodKlass&
&&&4:&&&&&&&&&28188&&&&&&&&3619568&&&methodKlass&
&&&5:&&&&&&&&&&2339&&&&&&&&2866712&&&constantPoolKlass&
&&&6:&&&&&&&&&&2038&&&&&&&&1698944&&&constantPoolCacheKlass&
&&&7:&&&&&&&&&&2339&&&&&&&&1659448&&&instanceKlassKlass&
&&&8:&&&&&&&&&28718&&&&&&&&&689232&&java.lang.String
&&&9:&&&&&&&&&16608&&&&&&&&&531456&&java.util.HashMap$Entry
&&10:&&&&&&&&&&&736&&&&&&&&&416896&&&methodDataKlass&
&&11:&&&&&&&&&&6144&&&&&&&&&369080&&[Ljava.lang.O
&&12:&&&&&&&&&&2620&&&&&&&&&254960&&java.lang.Class
&&13:&&&&&&&&&&&877&&&&&&&&&234768&&[Ljava.util.HashMap$E
&&14:&&&&&&&&&&3569&&&&&&&&&229624&&[S
&&15:&&&&&&&&&&3773&&&&&&&&&214248&&[[I
#创建堆转储(HPROF)
&C:\Users\Administrator&jcmd&7048&GC.heap_dump&filename=Myheapdump
Heap&dump&file&created&&&&
与jmap&-dump:file=&file&&&pid&功能一样
#创建一个堆直方图&
jcmd&&process&id/main&class&&GC.class_histogram&filename=Myheaphistogram
使用jmap&-histo&&pid&&
打印线程的栈信息
C:\Users\Administrator&jcmd&&7048&Thread.print
Full&thread&dump&Java&HotSpot(TM)&64-Bit&Server&VM&(24.75-b04&mixed&mode):
"ajp-bio-8009-AsyncTimeout"&daemon&prio=6&tid=0xbb000&nid=0x78c&waiting&on&condition&[0xf000]
&&&java.lang.Thread.State:&TIMED_WAITING&(sleeping)
&&&&&&&&at&java.lang.Thread.sleep(Native&Method)
&&&&&&&&at&org.apache.tomcat.util.net.JIoEndpoint$AsyncTimeout.run(JIoEndpoint.java:152)
&&&&&&&&at&java.lang.Thread.run(Thread.java:745)
&&&&&&&&.......{product}{C2 product}{pd product}{C1 product}{manageable}:运行时动态更改{C2 pd product}{ARCH product}{C1 pd product}{lp64_product}{product rw}(2)jstack 2.1 作用打印Java进程,核心文件或者远程调试服务器的Java线程堆栈跟踪.死锁监测和HANG使用jsadebugd 守护进程查询远程机器上的core文件及进程-l,可以打印java.util.concurrent.locks同步信息和堆上的同步器,没有该选项,仅仅是监视器的信息。jstack pid 与 ctrl+break也可以Thread.getAllStackTraces 2.2 语法jstack&[&options&]&pid
jstack&[&options&]&executable&core
jstack&[&options&]&[&server-id@&]&remote-hostname-or-IP每一个栈帧,打印信息包括类名,方法名,字节码索引(BCI),和行数。-m开关,同时打印本地和java栈帧信息。当指定的进程在一个64位Java虚拟机上运行,则可能需要指定-J-d64选项,例如:jstack -J-d64 -m pid。2.3 参数Options-F:强制dump-l:打印额外信息-m:打印混合堆栈信息(c++,java)/javase/8/docs/technotes/tools/unix/jstack.html/javase/8/docs/technotes/guides/troubleshoot/tooldescr016.html/javase/8/docs/technotes/guides/troubleshoot/tooldescr006.html/javase/8/docs/technotes/tools/windows/jcmd.html/javase/8/docs/technotes/guides/troubleshoot/tooldescr006.html本文出自 “” 博客,请务必保留此出处
了这篇文章
类别:┆阅读(0)┆评论(0)今天看啥 热点:
&ArrayList就是传说中的动态数组,就是Array的复杂版本,它提供了如下一些好处:动态的增加和减少元素、灵活的设置数组的大小......
& & 认真阅读本文,我相信一定会对你有帮助。比如为什么ArrayList里面提供了一个受保护的removeRange方法?提供了其他没有被调用过的私有方法?
& & 首先看到对ArrayList的定义:
public class ArrayList&E& extends AbstractList&E& &implements List&E&, RandomAccess, Cloneable, java.io.Serializable &
&从ArrayList&E&可以看出它是支持泛型的,它继承自AbstractList,实现了List、RandomAccess、Cloneable、java.io.Serializable接口。
& & AbstractList提供了List接口的默认实现(个别方法为抽象方法)。
& & List接口定义了列表必须实现的方法。
& & RandomAccess是一个标记接口,接口内没有定义任何内容。
& & 实现了Cloneable接口的类,可以调用Object.clone方法返回该对象的浅拷贝。
& & 通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。序列化接口没有方法或字段,仅用于标识可序列化的语义。
& & ArrayList的属性
& & ArrayList定义只定义类两个私有属性:
& & & * The array buffer into which the elements of the ArrayList are stored.&
& & & * The capacity of the ArrayList is the length of this array buffer.&
& & & */ &
& & &private transient Object[] elementD &
& & & * The size of the ArrayList (the number of elements it contains).&
& & & * @serial&
& & & */ &
很容易理解,elementData存储ArrayList内的元素,size表示它包含的元素的数量。 &
& 有个关键字需要解释:transient。 &
& Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。 &
ansient是Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进去的。 &
& 有点抽象,看个例子应该能明白。 &
public class UserInfo implements Serializable { &
& & &private static final long serialVersionUID = 019948L; &
& & &private S &
& & &private transient S &
& & &public UserInfo(String name, String psw) { &
& & & & &this.name = &
& & & & &this.psw = &
& & &public String toString() { &
& & & & &return &name=& + name + &, psw=& + &
&public class TestTransient { &
& & &public static void main(String[] args) { &
& & & & &UserInfo userInfo = new UserInfo(&张三&, &123456&); &
& & & & &System.out.println(userInfo); &
& & & & &try { &
& & & & & & &// 序列化,被设置为transient的属性没有被序列化 &
& & & & & & &ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream( &
& & & & & & & & & & &&UserInfo.out&)); &
& & & & & & &o.writeObject(userInfo); &
& & & & & & &o.close(); &
& & & & &} catch (Exception e) { &
& & & & & & &// TODO: handle exception &
& & & & & & &e.printStackTrace(); &
& & & & &} &
& & & & &try { &
& & & & & & &// 重新读取内容 &
& & & & & & &ObjectInputStream in = new ObjectInputStream(new FileInputStream( &
& & & & & & & & & & &&UserInfo.out&)); &
& & & & & & &UserInfo readUserInfo = (UserInfo) in.readObject(); &
& & & & & & &//读取后psw的内容为null &
& & & & & & &System.out.println(readUserInfo.toString()); &
& & & & &} catch (Exception e) { &
& & & & & & &// TODO: handle exception &
& & & & & & &e.printStackTrace(); &
& & & & &} &
&被标记为transient的属性在对象被序列化的时候不会被保存。
& & 接着回到ArrayList的分析中......
& & ArrayList的构造方法
& & 看完属性看构造方法。ArrayList提供了三个构造方法:
& & & * Constructs an empty list with the specified initial capacity.&
& & & */ &
& & &public ArrayList(int initialCapacity) { &
& & &super(); &
& & & & &if (initialCapacity & 0) &
& & & & & & &throw new IllegalArgumentException(&Illegal Capacity: &+ &
& & & & & & & & & & & & & & & & & & & & & & & & initialCapacity); &
& & &this.elementData = new Object[initialCapacity]; &
& & & * Constructs an empty list with an initial capacity of ten.&
& & & */ &
& & &public ArrayList() { &
& & &this(10); &
& & & * Constructs a list containing the elements of the specified&
& & & * collection, in the order they are returned by the collection's&
& & & * iterator.&
& & & */ &
& & &public ArrayList(Collection&? extends E& c) { &
& & &elementData = c.toArray(); &
& & &size = elementData. &
& & &// c.toArray might (incorrectly) not return Object[] (see 6260652) &
& & &if (elementData.getClass() != Object[].class) &
& & & & &elementData = Arrays.copyOf(elementData, size, Object[].class); &
& &第一个构造方法使用提供的initialCapacity来初始化elementData数组的大小。第二个构造方法调用第一个构造方法并传入参数10,即默认elementData数组的大小为10。第三个构造方法则将提供的集合转成数组返回给elementData(返回若不是Object[]将调用Arrays.copyOf方法将其转为Object[])。
& & ArrayList的其他方法
& & add(E e)
& & add(E e)都知道是在尾部添加一个元素,如何实现的呢?
public boolean add(E e) { &
& & ensureCapacity(size + 1); &// Increments modCount!! &
& & elementData[size++] = &
&书上都说ArrayList是基于数组实现的,属性中也看到了数组,具体是怎么实现的呢?比如就这个添加元素的方法,如果数组大,则在将某个位置的值设置为指定元素即可,如果数组容量不够了呢?
& & 看到add(E e)中先调用了ensureCapacity(size+1)方法,之后将元素的索引赋给elementData[size],而后size自增。例如初次添加时,size为0,add将elementData[0]赋值为e,然后size设置为1(类似执行以下两条语句elementData[0]=e;size=1)。将元素的索引赋给elementData[size]不是会出现数组越界的情况吗?这里关键就在ensureCapacity(size+1)中了。
& & 根据ensureCapacity的方法名可以知道是确保容量用的。ensureCapacity(size+1)后面的注释可以明白是增加modCount的值(加了俩感叹号,应该蛮重要的,来看看)。
& & & * Increases the capacity of this &tt&ArrayList&/tt& instance, if&
& & & * necessary, to ensure that it can hold at least the number of elements&
& & & * specified by the minimum capacity argument.&
& & & * @param & minCapacity & the desired minimum capacity&
& & & */ &
& & &public void ensureCapacity(int minCapacity) { &
& & &modCount++; &
& & &int oldCapacity = elementData. &
& & &if (minCapacity & oldCapacity) { &
& & & & &Object oldData[] = elementD &
& & & & &int newCapacity = (oldCapacity * 3)/2 + 1; &
& & & & & & &if (newCapacity & minCapacity) &
& & & & &newCapacity = minC &
& & & & & & &// minCapacity is usually close to size, so this is a win: &
& & & & & & &elementData = Arrays.copyOf(elementData, newCapacity); &
The number of times this list has been structurally modified.
& & 这是对modCount的解释,意为记录list结构被改变的次数(观察源码可以发现每次调用ensureCapacoty方法,modCount的值都将增加,但未必数组结构会改变,所以感觉对modCount的解释不是很到位)。
& & 增加modCount之后,判断minCapacity(即size+1)是否大于oldCapacity(即elementData.length),若大于,则调整容量为max((oldCapacity*3)/2+1,minCapacity),调整elementData容量为新的容量,即将返回一个内容为原数组元素,大小为新容量的数组赋给elementData;否则不做操作。
& & 所以调用ensureCapacity至少将elementData的容量增加的1,所以elementData[size]不会出现越界的情况。
& & 容量的拓展将导致数组元素的复制,多次拓展容量将执行多次整个数组内容的复制。若提前能大致判断list的长度,调用ensureCapacity调整容量,将有效的提高运行速度。
& & 可以理解提前分配好空间可以提高运行速度,但是测试发现提高的并不是很大,而且若list原本数据量就不会很大效果将更不明显。
& & add(int index, E element)
& & add(int index,E element)在指定位置插入元素。
public void add(int index, E element) { &
& & &if (index & size || index & 0) &
& & & & &throw new IndexOutOfBoundsException( &
& & & & &&Index: &+index+&, Size: &+size); &
& & &ensureCapacity(size+1); &// Increments modCount!! &
& & &System.arraycopy(elementData, index, elementData, index + 1, &
& & & & & & & size - index); &
& & &elementData[index] = &
& & &size++; &
& &首先判断指定位置index是否超出elementData的界限,之后调用ensureCapacity调整容量(若容量足够则不会拓展),调用System.arraycopy将elementData从index开始的size-index个元素复制到index+1至size+1的位置(即index开始的元素都向后移动一个位置),然后将index位置的值指向element。 & & &&
& & addAll(Collection&? extends E& c)
public boolean addAll(Collection&? extends E& c) { &
& & &Object[] a = c.toArray(); &
& & & & &int numNew = a. &
& & &ensureCapacity(size + numNew); &// Increments modCount &
& & & & &System.arraycopy(a, 0, elementData, size, numNew); &
& & & & &size += numN &
& & &return numNew != 0; &
& 先将集合c转换成数组,根据转换后数组的程度和ArrayList的size拓展容量,之后调用System.arraycopy方法复制元素到elementData的尾部,调整size。根据返回的内容分析,只要集合c的大小不为空,即转换后的数组长度不为0则返回true。
& & addAll(int index,Collection&? extends E& c)
public boolean addAll(int index, Collection&? extends E& c) { &
& & &if (index & size || index & 0) &
& & & & &throw new IndexOutOfBoundsException( &
& & & & &&Index: & + index + &, Size: & + size); &
& & &Object[] a = c.toArray(); &
& & &int numNew = a. &
& & &ensureCapacity(size + numNew); &// Increments modCount &
& & &int numMoved = size - &
& & &if (numMoved & 0) &
& & & & &System.arraycopy(elementData, index, elementData, index + numNew, &
& & & & & & & & & numMoved); &
& & & & &System.arraycopy(a, 0, elementData, index, numNew); &
& & &size += numN &
& & &return numNew != 0; &
& 先判断index是否越界。其他内容与addAll(Collection&? extends E& c)基本一致,只是复制的时候先将index开始的元素向后移动X(c转为数组后的长度)个位置(也是一个复制的过程),之后将数组内容复制到elementData的index位置至index+X。
& & clear()
public void clear() { &
& & &modCount++; &
& & &// Let gc do its work &
& & &for (int i = 0; i & i++) &
& & & & &elementData[i] = &
& & &size = 0; &
clear的时候并没有修改elementData的长度(好不容易申请、拓展来的,凭什么释放,留着搞不好还有用呢。这使得确定不再修改list内容之后最好调用trimToSize来释放掉一些空间),只是将所有元素置为null,size设置为0。
& & clone()
& & 返回此 ArrayList 实例的浅表副本。(不复制这些元素本身。)
public Object clone() { &
& & &try { &
& & & & &ArrayList&E& v = (ArrayList&E&) super.clone(); &
& & & & &v.elementData = Arrays.copyOf(elementData, size); &
& & & & &v.modCount = 0; &
& & & & & &
& & &} catch (CloneNotSupportedException e) { &
& & & & &// this shouldn't happen, since we are Cloneable &
& & & & &throw new InternalError(); &
& 调用父类的clone方法返回一个对象的副本,将返回对象的elementData数组的内容赋值为原对象elementData数组的内容,将副本的modCount设置为0。
& & contains(Object)
public boolean contains(Object o) { &
& & &return indexOf(o) &= 0; &
&indexOf方法返回值与0比较来判断对象是否在list中。接着看indexOf。
& & indexOf(Object)
public int indexOf(Object o) { &
& & &if (o == null) { &
& & & & &for (int i = 0; i & i++) &
& & & & &if (elementData[i]==null) &
& & & & & & & &
& & &} else { &
& & & & &for (int i = 0; i & i++) &
& & & & &if (o.equals(elementData[i])) &
& & & & & & & &
& & &return -1; &
通过遍历elementData数组来判断对象是否在list中,若存在,返回index([0,size-1]),若不存在则返回-1。所以contains方法可以通过indexOf(Object)方法的返回值来判断对象是否被包含在list中。
& & 既然看了indexOf(Object)方法,接着就看lastIndexOf,光看名字应该就明白了返回的是传入对象在elementData数组中最后出现的index值。
public int lastIndexOf(Object o) { &
& & &if (o == null) { &
& & & & &for (int i = size-1; i &= 0; i--) &
& & & & &if (elementData[i]==null) &
& & & & & & & &
& & &} else { &
& & & & &for (int i = size-1; i &= 0; i--) &
& & & & &if (o.equals(elementData[i])) &
& & & & & & & &
& & &return -1; &
采用了从后向前遍历element数组,若遇到Object则返回index值,若没有遇到,返回-1。
& & get(int index)
& & 这个方法看着很简单,应该是返回elementData[index]就完了。
public E get(int index) { &
& & &RangeCheck(index); &
& & &return (E) elementData[index]; &
但看代码的时候看到调用了RangeCheck方法,而且还是大写的方法,看看究竟有什么内容吧。
& & & * Checks if the given index is in range.&
&private void RangeCheck(int index) { &
& & &if (index &= size) &
& & & & &throw new IndexOutOfBoundsException( &
& & & & &&Index: &+index+&, Size: &+size); &
&就是检查一下是不是超出数组界限了,超出了就抛出IndexOutBoundsException异常。为什么要大写呢???
& & isEmpty()
& & 直接返回size是否等于0。
& & remove(int index)
public E remove(int index) { &
& & &RangeCheck(index); &
& & &modCount++; &
& & &E oldValue = (E) elementData[index]; &
& & &int numMoved = size - index - 1; &
& & &if (numMoved & 0) &
& & & & &System.arraycopy(elementData, index+1, elementData, index, &
& & & & & & & & & numMoved); &
& & &elementData[--size] = // Let gc do its work &
& & &return oldV &
首先是检查范围,修改modCount,保留将要被移除的元素,将移除位置之后的元素向前挪动一个位置,将list末尾元素置空(null),返回被移除的元素。
& & remove(Object o)
public boolean remove(Object o) { &
& & &if (o == null) { &
& & & & & & &for (int index = 0; index & index++) &
& & & & &if (elementData[index] == null) { &
& & & & & & &fastRemove(index); &
& & & & & & & &
& & & & &} &
& & &} else { &
& & & & &for (int index = 0; index & index++) &
& & & & &if (o.equals(elementData[index])) { &
& & & & & & &fastRemove(index); &
& & & & & & & &
& & & & &} &
& & & & &} &
& 首先通过代码可以看到,当移除成功后返回true,否则返回false。remove(Object o)中通过遍历element寻找是否存在传入对象,一旦找到就调用fastRemove移除对象。为什么找到了元素就知道了index,不通过remove(index)来移除元素呢?因为fastRemove跳过了判断边界的处理,因为找到元素就相当于确定了index不会超过边界,而且fastRemove并不返回被移除的元素。下面是fastRemove的代码,基本和remove(index)一致。
private void fastRemove(int index) { &
& & & & &modCount++; &
& & & & &int numMoved = size - index - 1; &
& & & & &if (numMoved & 0) &
& & & & & & &System.arraycopy(elementData, index+1, elementData, index, &
& & & & & & & & & & & & & & & numMoved); &
& & & & &elementData[--size] = // Let gc do its work &
& removeRange(int fromIndex,int toIndex)
protected void removeRange(int fromIndex, int toIndex) { &
& & &modCount++; &
& & &int numMoved = size - toI &
& & & & &System.arraycopy(elementData, toIndex, elementData, fromIndex, &
& & & & & & & & & & & & & numMoved); &
& & &// Let gc do its work &
& & &int newSize = size - (toIndex-fromIndex); &
& & &while (size != newSize) &
& & & & &elementData[--size] = &
执行过程是将elementData从toIndex位置开始的元素向前移动到fromIndex,然后将toIndex位置之后的元素全部置空顺便修改size。
& & 这个方法是protected,及受保护的方法,为什么这个方法被定义为protected呢?
& & 这是一个解释,但是可能不容易看明白。/questions/2289183/why-is-javas-abstractlists-removerange-method-protected
& & 先看下面这个例子
ArrayList&Integer& ints = new ArrayList&Integer&(Arrays.asList(0, 1, 2, &
& & & & & & & & &3, 4, 5, 6)); &
& & & & &// fromIndex low endpoint (inclusive) of the subList &
& & & & &// toIndex high endpoint (exclusive) of the subList &
& & & & ints.subList(2, 4).clear(); &
& & & & &System.out.println(ints); &
&输出结果是[0, 1, 4, 5, 6],结果是不是像调用了removeRange(int fromIndex,int toIndex)!哈哈哈,就是这样的。但是为什么效果相同呢?是不是调用了removeRange(int fromIndex,int toIndex)呢?
set(int index,E element)
public E set(int index, E element) { &
& & &RangeCheck(index); &
& & &E oldValue = (E) elementData[index]; &
& & &elementData[index] = &
& & &return oldV &
& 首先检查范围,用新元素替换旧元素并返回旧元素。
& & size()
& & size()方法直接返回size。
& & toArray()
public Object[] toArray() { &
& & & & &return Arrays.copyOf(elementData, size); &
&调用Arrays.copyOf将返回一个数组,数组内容是size个elementData的元素,即拷贝elementData从0至size-1位置的元素到新数组并返回。
& & toArray(T[] a)
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] = &
& & & & & &
&如果传入数组的长度小于size,返回一个新的数组,大小为size,类型与传入数组相同。所传入数组长度与size相等,则将elementData复制到传入数组中并返回传入的数组。若传入数组长度大于size,除了复制elementData外,还将把返回数组的第size个元素置为空。
& & trimToSize()
public void trimToSize() { &
& & &modCount++; &
& & &int oldCapacity = elementData. &
& & &if (size & oldCapacity) { &
& & & & & & &elementData = Arrays.copyOf(elementData, size); &
由于elementData的长度会被拓展,size标记的是其中包含的元素的个数。所以会出现size很小但elementData.length很大的情况,将出现空间的浪费。trimToSize将返回一个新的数组给elementData,元素内容保持不变,length很size相同,节省空间。
& & &学习Java最好的方式还必须是读源码。读完源码你才会发现这东西为什么是这么玩的,有哪些限制,关键点在哪里等等。而且这些源码都是大牛们写的,你能从中学习到很多。&
暂无相关文章
相关搜索:
相关阅读:
相关频道:
&&&&&&&&&&&&&&&&
Java编程最近更新}

我要回帖

更多关于 c字符串前面加 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信