1 finally和retrun
public static void main(String[] args) {
int result = m();
System.out.println(result);//输出的是100为什么?
}
/*
java语法规则(代码自上而下顺序执行)
java语法规则(return语句一旦执行,整个方法必须结束)
那么我们用反编译工具看看class文件为什么结果是100而不是101
反编译之后的代码
public static int m(){
int i =100;
int j = i;//这里他把i的的值赋给了j
i++;
return j;//最后返回了j
}
仔细思考下,代码自上而下执行,那么int i =100;下面的是不是return i?这里按照顺序就应该把i=100返回
但是,return又是最后执行的,这里为了保证本来return的是一个100,并且后面finally里的i++也要执行,
所以就把i的值赋给了j,返回了j(100),再执行i++ i的值变成了101
*/
public static int m(){
int i = 100;
try {
return i;//return是最后执行的,finally会先执行i++
}finally {
i++;
}
}
2 map集合
/*
map.put(k,v)实现原理
第一步:先将k,v封装到Node节点对象中
第二步:底层会调用k的hashCode()方法得出hash值
第三步:通过hash算法转换成数组的下标,下标位置如果没有任何元素
则把Node添加到这个位置上,如果说下标位置下对应有链表,此时会拿着k
和链表上每一个节点的k进行equals,如果所有的equals方法返回的都是false,
那么这个新节点会被添加到链表的末尾,如果有一个equals方法返回了true,
那么这个节点的value将会被覆盖
v = map.get(k)
先调用hashCode()得出hash值,hash算法转换成数组的下标,通过数组下标快速定位到某个位置,
如果位置上什么都没有,返回null。
如果这个位置上有链表,那么拿着参数k和链表上每个节点的k进行equals比较,如果equals返回false
那么get返回null
如果其中一个节点的k进行比较返回的是true,那么这个节点的value就是我们要返回的value
放在HashMap集合的k部分实际上是放在HashSet集合中
所以在HashSet集合中的元素同样需要重写equals()和hashCode()
哈希表使用不当时无法发挥性能
假设将hashCode()方法返回的hash值是固定的值,那么会导致底层哈希表变成了
纯单向链表,这种情况称之为:散列分布不均匀
什么是散列分布不均匀:假设有100个元素,10个单向链表,那么每个单向链表有十个节点,这就是最好的,
散列分布均匀的,如果所有节点这里50个那里3,4个就分布不均匀
那hash值全都不同可以吗?
那底层就变成数组了,也是散列分布不均匀
HashMap 集合的初始化容量为16,默认加载因子为0.75
这个默认加载因子是当HashMap集合底层的数组容量达到75%,数组开始扩容,而不是满了才扩容
重点:记住:HashMap集合初始化容量必须是2的倍数,这也是官方推荐的
这是因为达到散列分布均匀,为了提高HashMap集合的存取效率,所必须的
对于o1和o2,hash值相同,那么一定是放在同一个链表下的
如果o1和o2hash值不同,经过hash算法算出的数组下标可能是同一个, 这时发生"哈希碰撞"
就像数学7%3 = 1 4 %3 也是=1
*/
3 冒泡排序
public static void main(String[] args) {
//冒泡排序,最大的放在了右边
// 比如三个数字 三个数字要比两次,才能把最大的放右边, 然后剩下2个数,再比一次,再把最大的数放右边
// a b c a 和b比 b 比较大 , 然后 b 和c 比, c 比较大
// 下次剩下ab a 和 b比 b 比较大
int arr[] = {11,34,23,14,65};
for(int i=arr.length-1;i>0;i--)//使用i--的方式 每比较一次排除掉一个最大数再进行下次比较
{
for(int j=0;j<i;j++)
{
if(arr[j]>arr[j+1]) {
int temp;
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
for (int i = 0; i <arr.length ; i++) {
System.out.println(arr[i]);
}
}
4 选择排序
public static void main(String[] args) {
int[] arr = {11,25,21,33,22,77,69};
for (int i = 0; i <arr.length-1 ; i++) {
int min =i;//每次都认为当前下标就是最小值
for(int j=i+1;j<arr.length;j++) {
if (arr[min] > arr[j]) {
min = j;//循环比较之后把最小值的下标给min
}
if (min != i)
//上一个循环结束后判断min是否还等于一开始的i
// 如果不等于,将此时最小值的下标和一开始假设当前是最小值的下标互换位置
{
// 即如果此时最小值的下标为4,而一开始假设的最小值下标为0,
// 那么下标为4和下标为0的值互换,确保每次左边都是最小值
int temp;
temp = arr[min];
arr[min] = arr[i];//4 和0 互换
arr[i] = temp;//将最小值的下标放进了一开始假设的下标(相当于作弊)
}
}
}
for (int i = 0; i <arr.length-1 ; i++) {
System.out.println(arr[i]);
}
}
5 二分查找法
public static void main(String[] args) {
//二分法是基于排序后查找
int[] arr = {11,22,33,44,55,77,99};
int index = binarySearch(arr,44);
System.out.println(index==-1?"数组不存在":"下标"+index);
}
public static int binarySearch(int[] arr, int dest) {
int begin =0;//开始下标
int end = arr.length-1;//结束下标
while (begin<=end){//开始下标在结束下标的左边会一直循环
int mid = (begin+end)/2;
if(arr[mid]==dest){
return mid;//
}
if(dest>arr[mid]){
begin = mid +1; //数组下标在右边
}
if(dest<arr[mid]){
end = mid -1; //数组下标在左边
}
return -1;//没有找到
}
return dest;
}