Java基础知识回顾(一)

1.位运算(移动二进制的位数)

表现形式:位数移动后,没有数的补0

  • 全右移 (>>>) 比如 int i = num >>> 1(相当于 num / 2的结果)
  • 左移(<<)0011 0022 左移一位结果:0110 0220
  • 右移(>>)

2.算法:冒泡排序,选择排序,插入排序,二分法查找

/**
 * 冒泡排序
 */
class BubbleSort {

    public static void main(String[] args) {
        /**
         * 50 2 33 90 57 1
         * 2 33 50 57 1 《90》 第一轮
         * 2 33 50 1 《57》  第二轮
         * 2 33 1 《50》  第三轮
         * 2 1 《33》  第四轮
         * 1 《2》  第五轮
         *
         * @param args
         */
        Integer[] nums = {50, 2, 33, 90, 57, 1};
        // 外循环控制轮数
        for (int i = 0; i < nums.length - 1; i++) {
            for (int j = 0; j < nums.length - 1 - i; j++) {
                if (nums[j] > nums[j + 1]) {
//                    int temp = nums[j];
//                    nums[j] = nums[j+1];
//                    nums[j+1] = temp;
                    // nums[j] = nums[j+1]
                    nums[j] = nums[j] + nums[j + 1];
                    nums[j + 1] = nums[j] - nums[j + 1];
                    nums[j] = nums[j] - nums[j + 1];
                }
            }
        }

        for (int n = 0; n < nums.length; n++) {
            System.out.println(nums[n]);
        }
    }
}

/**
 * 选择排序
 */
class SelectorSort {

    /**
     * 选择第一个数为最小值||最大值 依次比较记录下标,最后换位
     * 50 2 33 90 57 1
     * 1 50 33 90 57 2 第一轮 (j = 1)
     * 1 2 50 90 57 33 第二轮 (j = 2)
     * 1 2 33 90 57 50 第三轮 (j = 3)
     * 1 2 33 50 90 57 第四轮 (j = 4)
     * 1 2 33 50 57 90 第五轮 (j = 5,包含本身,所以j<nums.length;)
     *
     * @param args
     */
    public static void main(String[] args) {
        Integer[] nums = {50, 2, 33, 90, 57, 1};
        for (int i = 0; i < nums.length - 1; i++) {
            int minIdx = i;
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[minIdx] > nums[j]) {
                    // 换下标
                    minIdx = j;
                }
            }
            // 判断需要交换 的数是否为自己
            if (minIdx != i) {
                nums[minIdx] = nums[minIdx] + nums[i];
                nums[i] = nums[minIdx] - nums[i];
                nums[minIdx] = nums[minIdx] - nums[i];
            }
        }
        for (int k = 0; k < nums.length; k++) {
            System.out.println(nums[k]);
        }
    }

}


/**
 * 插入排序
 */
class InsertSort{
    /**
     *
     * 从后往前进行比较,记住操作的数,如果操作的数小于前面的数,那就前面的数往后移动,最后在将记录的操作数替换到前面的数位置上
     * 50, 2, 33, 90, 57, 1
     * 50 50 33 90 57 1 记录操作数为2,第一轮,替换位置:2 50 33 90 57 1
     * 2 50 50 90 57 1 记录数为33 第二轮:替换位置:2 33 50 90 57 1
     * .....
     *
     */
    public static void main(String[] args) {

        Integer[] nums = {50, 2, 33, 90, 57, 1};

        for(int i = 1;i < nums.length; i++) {
            // 记录操作数
            int temp = nums[i];
            int j = 0;
            for(j = i - 1;j>=0;j--){
                if(nums[j] > temp){
                    nums[j + 1] = nums[j];
                } else {
                    break;
                }
            }
            // 因为上面剪掉了一个  所以是j+1
            if(nums[j+1] != temp){
                nums[j+1] = temp;
            }
        }

        // 打印输出
        System.out.println(Arrays.toString(nums));
    }
}


/*
* 二分法查找
*/
public class BinarySearch {

    /**
     * 前提  **必须排序好了的数组**
     * 定义一个数组最小的下标和最大的下标,相加除以2,判断这个数在左边还是右边,再继续查找
     *
     */
    public static void main(String[] args) {

        Integer[] nums = {50, 2, 33, 90, 57, 1};
        Arrays.sort(nums);
        System.out.println(searchMethod(nums,2));
    }

    public static int searchMethod(Integer nums[],int key) {
        int low = 0;
        int high = nums.length-1;
        while (low <= high)  {
            int middle = (low + high) >>> 1;
            if(nums[middle] > key){
                high = middle - 1;
            } else if(nums[middle] < key){
                low = middle + 1;
            } else {
                return middle;
            }
        }
        return -1;
    }

}

3.值传递和引用传递(分清楚数据在内存空间中存储的位置)

/**
 * 值传递
 */
class ValueTrans{
    /**
     * 基本数据类型存储在栈中;
     */
    public static void main(String[] args) {
        int num = 10;
        method(num);
        System.out.println(num); // 10
    }

    public static void method(int num1){
        num1 = 20;
    }
}

/**
 * 引用传递
 */
class RefTrans{
    public static void main(String[] args) {
        Duck duck = new Duck(10);
        method(duck);
        System.out.println(duck.getAge()); // 20
    }

    public static void method(Duck d){
        d.setAge(20);
    }

}

/**
 * 字符串引用类型传递
 */
class StrTrans{
    public static void main(String[] args) {
        String name = "狒狒";
        method(name);
        System.out.println(name); // 狒狒
    }

    public static void method(String name2){
        name2 = "晓晓";
    }
}

/**
 * 字符串对象引用类型传递
 */
class StrTransObject{
    public static void main(String[] args) {
        Duck d1 = new Duck("甜甜");
        method(d1);
        System.out.println(d1.getName()); //
    }

    public static void method(Duck d2){
        d2.setName("恺恺");
    }
}

详解图
Java基础知识回顾(一)

4.静态关键字(static):存储在静态方法区中,只存储一份,是共享的数据,依赖于类,使用类来调用即可。

5.代码块

  • 普通代码块,在方法中写的代码块(作用:限制作用域)
  • 构造块:在类中定义的代码块,在创建对象时被调用,优先于构造方法执行
  • 静态代码块:在类中使用static定义的代码块,在第一次使用的时候被调用(创建对象时),只执行一次,优于构造块
    (通常会使用静态代码块来初始化只调用一次的数据。)
  • 同步代码块(sync{})

单例设计模式:(饿/懒汉式)

单例模式的思想在于保证工具类仅有一个实例对象,为了节省重复创建对象所带来的内存消耗,从而提高效率。

在项目中为什么要使用单例?
1、在设计一些工具类的时候(通常工具类,只有功能方法,没有属性)
2、工具类可能会被频繁调用

???能否使用构造方法私有化 + 静态方法来代替单例???

class Tools{
	privtae Tools(){};
	
	public static void print1(){};
	
	public static void print2(){};
}

小结:是可以代替的,但是相对单例模式来说静态方法占用空间,单例模式更优。在JDK中Math类就是使用了构造方法私有化 + 静态方法来构建一系列的静态方法。

上一篇:Base64编码过程


下一篇:tomcat8.5.57源码阅读笔记5.1 - 管道