今天读程序遇到有for循环里有冒号,去查了下,属于增强for循环
1 | for(元素变量:元素集合) |
1 | import java.util.ArrayList; |
今天读程序遇到有for循环里有冒号,去查了下,属于增强for循环
1 | for(元素变量:元素集合) |
1 | import java.util.ArrayList; |
public void Helper(TreeNode root,List<String> list, String path)
前面两者不必说,传递的是地址,叫 emm 叫值传递——java中只存在值传递,只存在值传递!!! (然而我们经常看到对于对象(数组,类,接口)的传递似乎有点像引用传递,可以改变对象中某个属性的值。但是不要被这个假象所蒙蔽,实际上这个传入函数的值是对象引用的拷贝,即传递的是引用的地址值,所以还是按值传递。) 再来看一看String的问题,String是对象,但是表现出像基本数据类型一样的值传递表现,比较一下下面两者:1 | public class Test3 { |
输出10,50
1 | public class Test { |
输出lisi lisi
照理说String是对象,应该输出lisi zhangsan才对啊,怎么change方法里没把String改掉呢?这是因为String具有不变性,看下图 来源
String具有不可变性,String被重新赋值为abcdel时,是在堆内重新开辟空间放入abcdel,并且String指向它,相当于新建了一个String对象,但是原先的String s=abcd仍然存在。
同理对于上面change方法里重新建立了一个String zhangsan对象,回到main里,zhangsan对象地址由于是值传递,在main里当然就消失了,此时的s仍然是lisi这个对象.
2. 再从根本上来看下为什么String具有这种不变性
翻开JDK源码,java.lang.String类起手前三行,是这样写的:
1 | public final class String implements java.io.Serializable, Comparable<String>, CharSequence { |
首先String类是用final关键字修饰,这说明String不可继承。
再看下面,String类的主力成员字段value是个char[ ]数组,而且是用final修饰的。final修饰的字段创建以后就不可改变。
有的人以为故事就这样完了,其实没有。因为虽然value是不可变,也只是value这个引用地址不可变。挡不住Array数组是可变的事实。Array的数据结构看下图,
也就是说Array变量只是stack上的一个引用,数组的本体结构在heap堆。String类里的value用final修饰,只是说stack里的这个叫value的引用地址不可变。没有说堆里array本身数据不可变。看下面这个例子,
1 | final int[] value={1,2,3} |
所以String是不可变,关键是因为SUN公司的工程师,在后面所有String的方法里很小心的没有去动Array里的元素,没有暴露内部成员字段。private final char value[]这一句里,private的私有访问权限的作用都比final大。而且设计师还很小心地把整个String设成final禁止继承,避免被其他人继承后破坏。所以String是不可变的关键都在底层的实现,而不是一个final。考验的是工程师构造数据类型,封装数据的功力。
[1] 胖胖. 如何理解 String 类型值的不可变[EB/OL]. https://www.zhihu.com/question/20618891.
List<String> list = new ArrayList<>(2);
list.size()
一个数组是有序数组,则mid=(start+end)/2即是中间位置。
倘若是一个有序链表呢?
转换为数组?——数组size怎么确定。暂时设大点吧
第一次遍历记录size,第二次再到size/2位置
也许方法很多,但是今天可以通过快慢指针来完成:
快慢指针中的快慢指的是移动的步长,即每次向前移动速度的快慢。例如可以让快指针每次沿链表向前移动2,慢指针每次向前移动1次。
该方法在不借助计数器变量实现寻找中位数的功能。原理是:快指针的移动速度是慢指针移动速度的2倍,因此当快指针到达链表尾时,慢指针到达中点。程序还要考虑链表结点个数的奇偶数因素,当快指针移动x次后到达表尾(1+2x),说明链表有奇数个结点,直接返回慢指针指向的数据即可。如果快指针是倒数第二个结点,说明链表结点个数是偶数,这时可以根据“规则”返回上中位数或下中位数或(上中位数+下中位数)的一半。
1 | while (fast&&slow) |
具体地,可以拿leetcode 109题 练手。
具体可以参考下关于快慢指针的若干应用详解.