复习java

基础语法

二维数组和Object类中那些方法还没
2020年8月4日12:10:24

注释

//行内注释
/*
多行注释
*/
/**
文档注释 javadoc生成帮助文档
*/

标识符

关键字

在这里插入图片描述

数据类型

基本数据类型

整数

byte 1
short 2
int(默认) 4
long 8
0B 二进制
0 八进制
0X 十六进制

浮点数

float 4
double(默认) 8

字符

char 2 上面单位都是字节

‘\u0000’

\b 退格
\n 换行
\t 水平制表(HT) (跳到下一个TAB位置)
\r 回车
’ 代表一个单引号(撇号)字符
" 代表一个双引号字符
\ 代表一个反斜线字符’’’

布尔值

boolean 1位

引用数据类型


接口
数组

类型转换

自动类型转换

低转高

byte b = 10;
int i = 5;
i = b;//所谓低转高就是 把低的赋给高的

强制类型转换

高转低
低 = (低)高

byte b = 10;
int i = 5;
b = (byte)i;//先将 i强制转换成byte类型再赋给b

字符串与数字的转换

数字变成字符串

		int i = 100;
		String s;
		//1
		s = i + "";
		System.out.println("s = " + s);
		
		//2
		Integer it = new Integer(i);
		s = it.toString();
		System.out.println("s = " + s);
	
		//3
		s = Integer.toString(i);
		System.out.println("s = " + s);
		
		//4
		s = String.valueOf(i);

字符串变成数字

int i = 100;
String s = "123";

i = Integer.parseInt(s);
System.out.println(i);

变量和常量

变量

最普通的
type varName (=value);

//如
int i;
char a,b,c;
double d = 1.1;

引用变量(55页)

而当变量指向一个对象时,这个变量就被称为引用变量

假如自定义了一个Dog类
Dog myDog = new Dog();
比如 一个Dog的杯子 里面放入 myDog这个遥控器(只能是控制Dog的遥控器)
后面部分就是 Java虚拟机分配堆空间给新建立的Dog对象
等于号 表示 将 引用变量与刚刚建立的 连接起来
取得Dog对象的方法字节的形式存放到myDog这个引用变量中
相当于 将 新建立的Dog对象的地址告诉引用变量 然后引用变量就指向了堆中的Dog变量

作用域

指可访问变量的一段代码,在程序中不同的地方声明的变量具有不同的作用域,例如:局部变量,全局变量等。

类变量

(静态变量 也就是用static修饰 然后就从属于类了)

  • 静态变量被所有对象共享,在内存中只有一个副本,在类初次加载的时候才会初始化
  • 非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响
public class Staticbl {
	public static void main(String[] args) {
		System.out.println(SBL.i);//10
//		System.out.println(BL.m);//区别 1 静态变量可以直接类名.变量名  而实例变量(类中方法外)不行
		SBL b1 = new SBL();
		SBL b11 = new SBL();
		BL b2 = new BL();
		BL b22 = new BL();
		System.out.println(b2.m);//10
		
		b1.add();
		b2.add();
		
		System.out.println(b1.i);//20   最好是SBL.i
		System.out.println(b2.m);//20
		
		System.out.println(b11.i);//20  区别2 因为加了static的静态变量是直属于类的  通常都是用类名.输出    所以大家用的都是同一个(不区分b1 与  b11)
		System.out.println(b22.m);//10
	}
}

class SBL{
	public static int i = 10;
	
	public void add() {
		i += 10;
	}
}

class BL{
	public int m = 10;
	
	public void add() {
		m += 10;
	}
}
成员变量(全局变量)与局部变量
  1. 定义的位置不一样【重点】
    局部变量 在方法内部
    成员变量 在方法外部,直接写在类中
  2. 作用范围不一样【重点】
    局部变量 只有在方法中才可以使用,出了方法就不能
    成员变量 整个类全都可以通用
  3. 默认值不一样【重点】
    局部变量 没有默认值 必须先手动赋值
    成员变量 有默认值
  4. 内存的位置不一样(了解)
    局部变量 位于栈内存
    成员变量 位于堆内存
  5. 生命周期不一样(了解)
    局部变量 随着方法进栈而诞生,随着方法出栈而消失
    成员变量 随着对象创建而诞生,随着对象被垃圾回收而消失
/*
 * 输出结果为12  问题为什么a不用初始化   因为a b 是成员变量有默认值
 * 简单来说 成员变量是声明在类中的  
 * 		 局部变量是声明在方法中
 * 假如add方法里面的sum需要进行运算 如 sum += 1;这样就不行
 */
public class A_关于全局变量与局部变量 {
	public static void main(String[] args) {
		System.out.println(new AddThing().add());
	}
	
	public void method(int param){//方法的参数就是局部变量
		//参数在方法调用的时候,必然会被赋值
		System.out.println(param);
	}

}

class AddThing{
	int a;
	int b = 12;
	
	public int add() {
		int sum;
		int x;
		//sum = a + x;//error
		sum = a + b;
		return sum;
	}
}

关于成员变量扩展

其中实例变量、类变量、常量都是属于成员变量的,成员变量又被称为全局变量,
成员变量的范围比实例变量更宽泛

public class A{
	String id; //实例变量
	private String Tel; //实例变量
	private int size; //实例变量
	private static String depart; //类变量
	final String design="样式"; //常量
}

常量

不可改变的就是常量
final MAX_A = 10;
全大写

命名规范

  • 见名知意
  • 驼峰命名(变量,方法)
  • 类是 首字母大写的驼峰命名
  • 常量 大写+下划线

运算符

  1. 算术运算符
+  -  *  /  %  ++  --
  1. 赋值运算符 =
  2. 关系运算符
>= <= == != instanceof

instanceof的作用是判断其左边对象是否为其右边类的实例

public static void main(String[] args) {
		Integer i = new Integer(2);
		System.out.println(i instanceof Object);//true
		A a = new A();
		B b = new B();
		C c = new C();
		D d = new D();
		
		a instanceof A true
		a instanceof B(C) false
		b(c) instanceof A true
		c instanceof B //以及反过来  error
		d instanceof A(B、C)// error
		d instanceof Object true
	}
}
class A{}
class B extends A{}
class C extends A{}
class D{}
  1. 逻辑运算符
&& || !
  1. 位运算符
& | ^(异或) ~(取反)  >> << >>>
  1. 条件运算符
    熟悉这个
? :

int a = 3, b = 5;
System.out.println(a>b?a:b);// 输出 5
  1. 扩展运算符
+=  -=  *=  /=

包机制

  • 域名倒写
  • package
  • import 导入包

JavaDoc

  • JDK帮助文档
  • Javadoc
public class A{
/**
* @author 作者
* @Version 版本
* @since JDK多少 1.0
* @param args 命令参数
* @return 返回
* @throws 没有异常
*/
	public static void main(String[] args){
	}
}

cmd命令
javadoc -encoding UTF-8 -charset UTF-8 A.java

流程控制

Scanner

用户交互 System.in

import java.util.Scanner;

public class A{
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		//System.in表示键盘输入  结合System.out输出到控制台 
        int num = sc.nextInt();
        System.out.println("输入的数字是:" + num);

        String s = sc.next();
        System.out.println("输入的字符是:" + s);

		//使用匿名对象  节约内存
		System.out.println("输入的数字是:" + new Scanner(System.in).nextInt());
	}

}

顺序结构

程序的默认结构 自上而下的执行

选择结构

  • if 单选择
  • if else 双选择
  • if else if else 多选择
  • switch( Java1.7之后的版本才开始支持switch字符串,但是内部实现case还是基于整形变量的匹配

switch

case 穿透现象 没有break就接着执行下一个case
break 跳出循环
default 默认的选项 (就是除了写的case之外的都走default这一条)

循环结构

  • while
  • do…while (肯定会执行一次)
  • for
  • 增强for循环
package text;
/*
 * 简化了数组和集合的遍历,可以用来替代迭代器
 */
public class ForPlus {
	public static void main(String[] args) {
		String[] str = {"1","2","3"};
		
		for (String s : str) {
			System.out.println(s);
		}
	}
}

break&&continue

  • break 跳出循环 循环结束
  • continue 终止这次循环 继续下一次循环
  • 带标签的continue :终止本次循环 跳到标签位置进行接下来的循环
  • 带标签的break : 同理终止结束到标签 结束语句
for(int i=0; i<10; i++)
{
	if(i == 5)
	continue;//如果是break  输出就是01234
	System.out.print(i);
}
//012346789 没有5 因为当i等于5的时候 这次循环结束 下一次循环
  • return 结束方法的运行

方法

方法的定义

修饰符 返回值 方法名(参数名字){
如果有返回值就
return 返回值;
}

public int INTFF(int i){
	x = i+1;
	return x;
}

方法的调用

  • 类名.方法
  • 对象.方法

别人的方法的重载与重写

重载

方法名字相同,而参数不同。返回类型可以相同也可以不同。

public class Overloading {
    public int test(){
        System.out.println("test1");
        return 1;
    }

    public void test(int a){
        System.out.println("test2");
    }   
 
    //以下两个参数类型顺序不同
    public String test(int a,String s){
        System.out.println("test3");
        return "returntest3";
    }   
 
    public String test(String s,int a){
        System.out.println("test4");
        return "returntest4";
    }   
 
    public static void main(String[] args){
        Overloading o = new Overloading();
        System.out.println(o.test());			//输出test1
        o.test(1);								//输出test2
        System.out.println(o.test(1,"test3"));	//输出test3
        System.out.println(o.test("test4",1));	//输出test4
    }
}

重写

/*
 * 重写的意义就是对父类的方法不满意 想修改父类的方法
 * 重写方法 必须和 被重写方法 的外壳全部一样 只能方法里的内容不一样
 * 重写方法的权限  必须比  被重写方法的权限 高
 * 再详细看链接
 * 
 */
public class A方法的重写 {
	public static void main(String[] args) {
		B b = new B();
		b.f(10100);
		
	}
}
class A{
	public int f(int i) {
		System.out.println("A");
		return 1;
	}

}

class B extends A{
//	权限低了就报错
//	private int f(int i) {
//		System.out.println("B");
//		return 2;
//	}
	public int f(int i) {
		System.out.println("B");
		return 2;
	}
}

命令行传参

给main方法传参

public class Test {
	public static void main(String[] args) {
		for(String s : args){
			System.out.println(s);
		}
	}
}

在这里插入图片描述

可变长参数

Java从JDK1.5以后的
使用前提:

  • 当方法的参数列表数据类型已经确定,但是参数的个数不确定就可以使用可变参数。

使用格式 定义方法时使用

  • 修饰符 返回值类型 方法名(数据类型…变量名){ }

可变参数的原理

  • 可变参数底层就是一个数组,根据传递的参数格式不同,会创建不同长度的数组,来存储这些参数
  • 传递的参数个数,可以是0个(不传递),1,2…多个
package text;

public class Max {
	public static void main(String[] args) {
		System.out.println(getMax());//不传入任何参数
		System.out.println(getMax(1,2,3,4));//传入可变参数
		System.out.println(getMax(new int[] {1,222,3,4}));//传入数组,因为可变参数的实现就是用数组
		System.out.println(getLow(4, new int[] {1,2,3,4,5}));
	}
	
	public static int getMax(int... nums) {
		if(nums.length == 0) {
			System.out.println("没有传入参数");
			return 0;
		}
		else {
			int max = 0;
			for (int i: nums) {
				max = (i>max) ? i : max;
			}
			return max;
		}
	}
	public static int getLow(int num,int... nums) {
		//如果一个方法中不止一个参数,那么可变参数列表必须放到最后
		int cnt = 0;
		for (int i:nums) {
			if(i<num)
			{
				cnt++;
			}
		}
		return cnt;
	}
}

可变参数的特殊写法

public void X(Object... obj){

}

递归

自己调用自己
时间复杂度高

数组

数组的定义

int[] a = new int[5];
int[] b = {1,2,3};

数组的使用

import java.util.Arrays;

public class A一维数组的使用 {
	public static void main(String[] args) {
		MyDate[] m;
		m = new MyDate[10];
		for (int i=0; i<10; i++) {
			m[i] = new MyDate(2000+i, i+1, i+1);
			m[i].display();
		}
		
//-----------------------------------------------------------------------------------------		
		//数组的覆盖
//		int[] a = {1, 2, 3, 4, 5};
//		int[] b = {6, 7, 8, 9, 0};
//		System.arraycopy(a, 0, b, 1, 2);//把a数组下标从 0 (包括0)开始覆盖掉 b 数组 下标 从  1(包括1) 开始  覆盖长度为 2;
//		for (int j=0; j<a.length; j++) {
//			System.out.printf("%d ",a[j]);
//		}// 1 2 3 4 5 
//		System.out.println();
//		for (int j=0; j<b.length; j++) {
//			System.out.printf("%d ",b[j]);
//		}// 6 1 2 9 0
//-------------------------------------------------------------------------------------------
		//数组的排序
//		int[] p = {2, 5, 7, 1, 6, 9, 0};
//		System.out.println("排序前");
//		showArray(p);
//		
//		Arrays.sort(p);
//		
//		System.out.println("排序后");
//		showArray(p);
//------------------------------------------------------------------------------------------		
		
	}
	
	public static void showArray (int[] a){
		for (int e : a)//把a取出来给e 循环
			System.out.printf("%d ",e);
		System.out.println();
		
//		for (int i=0; i<a.length; i++)
//			System.out.printf("%d ",a[i]);
//		System.out.println();
	}

}

class MyDate{
	private int day;
	private int month;
	private int year;
	public MyDate(int y, int m, int d) {
		day = d;
		month = m;
		year = y;
	}
	public void display() {
		System.out.println(year +"-"+ month +"-"+ day);
	}
}
/* 输出为
2000-1-1
2001-2-2
2002-3-3
2003-4-4
2004-5-5
2005-6-6
2006-7-7
2007-8-8
2008-9-9
2009-10-10
*/

ArrayIndexoutofBoundsException
数组下标越界异常

二维数组

待定

Arrays工具类

java.util.Arrays是一个与数组相关的工具类,里面提供了大量静态方法,用来实现数组常见的操作。

public static String toString(数组); 将参数数组变成字符串(按照默认格式:[元素1, 元素2, 元素3...]public static void sort(数组); 按照默认升序(从小到大)对数组的元素进行排序。

备注:

  1. 如果是数值,sort默认按照升序从小到大
  2. 如果是字符串,sort默认按照字母升序
  3. 如果是自定义的类型,那么这个自定义的类需要有Comparable或者Comparator接口的支持。

如 Arrays.sort(数组名字);
就是排序
别人的Arrays详解

排序算法

冒泡排序

import java.util.Arrays;
public class Maopao {
	public static void main(String[] args) {
		//冒泡排序原理:数组元素两两比较,交换位置,大元素往后放,那么经过一轮比较后,最大的元素,就会出现在最大索引处。
		//0和1比  然后  1和2比   2和3比
		int[] arr = {122, 3, 88, 5, 10};
		for(int j=0; j<arr.length-1; j++) {
			for(int i=0; i<arr.length-1-j; i++) {
				if(arr[i] > arr[i+1]) {
					int t = arr[i];
					arr[i] = arr[i+1];
					arr[i+1] = t;
				}
			}
		}
		System.out.println(Arrays.toString(arr));
	}
}

选择排序

import java.util.Arrays;

public class Xuanze {
	public static void main(String[] args) {
		//选择排序原理:从0索引处开始,依次和后面的元素进行比较,小的元素往前放,经过一轮比较后,最小的元素就出现在了最小索引处
		//0和1比 0和2比 0和3比   然后  1和2比  1和3比
		int[] arr = {11, 55, 2, 999, 343};
		for(int index=0; index<arr.length-1; index++) {
			for(int i=index+1; i<arr.length-1; i++) {
				if(arr[index]>arr[i]) {
					int t = arr[index];
					arr[index] = arr[i];
					arr[i] = t;
				}
			}
		}
		System.out.println(Arrays.toString(arr));
	}
}

直接插入排序

import java.util.Arrays;

public class Zhijiecharu {
	public static void main(String[] args) {
		//直接插入排序原理:算法思路:直接插入排序,是一种最简单的排序方法 他的基本操作是将一个记录插入到一个长度为m的有序表中,使之仍保持有序。
		//{3} {2, 3} {2, 3, 56}  每次插入一个 倒着比较 小的放前面
		int[] arr = {3, 2, 56, 78, 0, 1};
		for(int i=1; i<arr.length; i++) {
			int j = i;
			while(j>0 && arr[j]<arr[j-1]) {
				int t = arr[j];
				arr[j] = arr[j-1];
				arr[j-1] = t;
				j--;
			}
		}
		
		System.out.println(Arrays.toString(arr));

	}
}

希尔排序

public class Xier {
    public static void main(String[] args) {
        //希尔排序:对插入排序的优化  选取合适的增量经过一轮排序后,就会让序列大致有序
        //然后再不断的缩小增量,进行插入排序,直到增量为 1那整个排序结束
        //直接插入排序 就是 增量为1 的希尔排序
        int[] arr = {66, 45, 22, 2, 55, 99};
        int h = arr.length/2;
        while (h >= 1){
            for (int i=h; i<arr.length; i++){
                for (int j=i; j>h-1; j-=h){
                    if (arr[j] < arr[j-h]){
                        int t = arr[j];
                        arr[j] = arr[j-h];
                        arr[j-h] = t;
                    }
                }
            }
            h /= 2;
        }
        System.out.println(Arrays.toString(arr));

    }
}

快速排序

import java.util.Arrays;

public class Kuaisu {
    public static void main(String[] args) {
        int[] arr = {123, 4, 8 ,9 ,20, 0, 19};

        //定义快速排序的方法  数组 开始位置  结束位置
        //              通常 开始位置和结束位置 就是数组的全部
        quickSort(arr, 0, arr.length-1);
        System.out.println(Arrays.toString(arr));
    }


//        分治法:比大小,再分区
//            1.从数组中取出一个数,作为基准数。
//            2.分区:将比这个数大或等于的数全放到他的右边,小于他的数,全放到他的左边。
//            3.再对左右区间重复第二步,直到各区间只有一个数。


    private static void quickSort(int[] arr, int start, int end) {
        //找出分左右两区的的索引位置,然后对左右两区进行递归调用
        if (start<end){
            int index = getIndex(arr, start, end);//先找到索引位置
            //然后对左右两区进行递归调用
            quickSort(arr, start, index-1);
            quickSort(arr, index+1, end);
        }
    }
    //找到索引位置的同时 进行排序 将比索引位置的数 大或等于 的数全放到他的右边,小于他的数,全放到他的左边。
    private static int getIndex(int[] arr, int start, int end) {
        int i = start;//用i接收 排序开始的数的位置
        int j = end;  //用j接收 排序结束的数的位置

        int x = arr[i];//1.从数组中取出一个数,作为基准数。


        while (i<j){//
            //由后向前找比他小的数,找到后挖出此数填到前一个坑中。
            while (i<j && arr[j]>=x){
                j--;
            }
            if (i<j){
                arr[i] = arr[j];
                i++;
            }
            //由前向后找比他大或等于的数,找到后也挖出此数填到前一个坑中。
            while (i<j && arr[i]<x){
                i++;
            }
            if (i<j){
                arr[j] = arr[i];
                j--;
            }
        }

        arr[j] = x;//把基本数填到一个坑

        return i;
    }
}

归并排序

public class Guibing {
    /*
    归并排序 就是利用归并的思想实现排序的方法。
    它的原理是假设初始序列有N个记录,则可以看成是N个
    有序的子序列,每个子序列的长度为1,然后两两归并,
    得到N/2个长度为2或1的有序子序列,再两两归并....
    如此重复,直至得到一个长度为N的有序序列为止,这种
    排序方法称为2路归并排序,

    理解 先递归拆分到最小 再慢慢归并  归并一次就是实现 小到大 的排序
     */
    public static void main(String[] args) {
        //初始待排序的数组
        //int[] arr = {1, 3, 2, 4, 9 , 6, 7, 5, 8, 10};
        //int[] arr = {5,6,7,8,   1,2,3,4};
        int[] arr = {3,9,4};

        //拆分
        chaiFen(arr, 0, arr.length-1);

        //归并
        //guiBing(arr, 0, 3, arr.length-1);

        //输出原数组
        System.out.println(Arrays.toString(arr));
    }

    private static void chaiFen(int[] arr, int startIndex, int endIndex) {
        //计算中间索引
        int centerIndex = (startIndex+endIndex)/2;
        if (startIndex < endIndex){
            //分成两边拆
            chaiFen(arr, startIndex, centerIndex);
            chaiFen(arr, centerIndex+1, endIndex);
            guiBing(arr,startIndex,centerIndex,endIndex);
        }
    }

    private static void guiBing(int[] arr, int startIndex, int centerIndex, int endIndex) {
        //定义一个临时数组
        int[] temArr = new int[endIndex - startIndex + 1];

        //定义左边数组的起始索引
        int i = startIndex;

        //定义右边数组的起始索引
        int j = centerIndex+1;//注意 + 1

        //定义临时数组的起始索引
        int index = 0;

        //比较左右两个数组的元素大小,往临时数组中放
        while(i<=centerIndex && j<=endIndex){
            //对半分  左边第一个与右边第一个比较 谁小就放入临时数组第一个
            if (arr[i] <= arr[j]){
                temArr[index] = arr[i];
                i++;
            }else {
                temArr[index] = arr[j];
                j++;
            }
            index++;
        }
        //如果不是偶数长度则会出现剩余的
        //处理剩余元素
        while (i <= centerIndex){
            temArr[index] = arr[i];
            i++;
            index++;
        }
        while (j <= endIndex){
            temArr[index] = arr[j];
            j++;
            index++;
        }
        //将临时数组中的元素取到原数组中
        for (int k=0; k<temArr.length; k++){
            arr[k+startIndex] = temArr[k];
        }
    }
}

基数排序

import java.util.Arrays;

public class Jishu {
    /*
    基数排序不同于之前所介绍的各类排序,
    前边介绍到的排序方法或多或少的是通过使用比较和移动记录来实现排序,
    而基数排序的实现不需要进行对关键字的比较,
    只需要对关键字进行“分配”与“收集”两种操作即可完成。
     */
    public static void main(String[] args) {
        //基数排序 通过分配再收集的方式进行排序
        int[] arr = {2, 1, 60, 49, 123, 45, 0, 40};
        
        jishuPaixu(arr);

        System.out.println(Arrays.toString(arr));


    }

    private static void jishuPaixu(int[] arr) {
        //定义二维数组,放10个桶
        int[][] tempArr = new int[10][arr.length];

        //定义统计数组
        int[] counts = new int[10];//统计每个桶中有几个数 同时还确定了位置 比如tempArr[0][]这个时候第一次表示个位为0的数 接着看36行
        //默认counts[0-9]都是0
        //首先得确定最大的是几位数就得排几轮
        int max = getMar(arr);
        int len = String.valueOf(max).length();//将最大的数变成字符串之后 长度就是它有几位

        for (int i = 0, n = 1; i < len; i++,n *= 10) {//循环轮次
            for (int j = 0; j < arr.length; j++) {
                //获取每个 位上的数
                int ys = arr[j]/n % 10;
                tempArr[ys][counts[ys]++] = arr[j];//这里是36行  如 有一个余数2的 tempArr[2][0]存放 然后counts[2]就等于了1 表示了2这个桶里面有了一个数了
            }
            //取出桶中的元素
            int index = 0;
            for (int k = 0; k < counts.length; k++) {//遍历统计数组 counts[1]表示的就是1这个桶里面有多少个数  k就是几号桶
                if (counts[k] != 0){//如果统计数组中 有数 就是不等于0的情况 才取出来
                    for (int h = 0; h < counts[k]; h++) {//h就是k号桶有h个数
                        //从桶中取出元素放回原数组
                        arr[index] = tempArr[k][h];//例如 将1号桶的第2个数放进原数组
                        index++;
                    }
                    counts[k] = 0;//清除上一次统计的个数
                }
            }
        }
    }

    private static int getMar(int[] arr) {
        int max = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if (max < arr[i])
                max = arr[i];
        }
        return max;
    }
}

堆排序

import java.util.Arrays;

public class Dui {
    /*
    堆排序
        1.将待排序序列构造成一个大顶堆, 此时,整个序列的最大值就是堆顶的根节点。
        2.将其与末尾元素进行交换,此时末尾就为最大值。
        3.然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。
        4.如此反复执行,便能得到一个有序序列了.

     */
    public static void main(String[] args) {
        //定义一个数组
        int[] arr = {1, 3, 0, 45, 33, 98};
        //调整成大顶堆的方法
        //定义开始调整的位置  就是最后一个非叶子结点
        int startIndex = (arr.length-1)/2;
        //循环开始调
        for (int i=startIndex; i>=0; i--){
            toMaxHeap(arr,arr.length,i);
        }

        //经过上面的操作后,已经把数组变成了一个大顶堆,把根元素和最后一个元素进行调换
        for(int i=arr.length-1; i>=0; i--){
            //进行调换
            int t = arr[0];
            arr[0] = arr[i];
            arr[i] = t;
            //换完之后,我们再把剩余元素调成大顶堆
            toMaxHeap(arr, i, 0);
        }
        System.out.println(Arrays.toString(arr));
    }
    /**
     *
     * @param arr 要排序的数组
     * @param size 调整的元素个数
     * @param index 从哪里开始调整
     */
    private static void toMaxHeap(int[] arr, int size, int index) {
        //获取左右子节点的索引
        int leftNodeIndex = index*2+1;
        int rightNodeIndex = index*2+2;
        //查找最大节点所对应的索引
        int maxIndex = index;
        if (leftNodeIndex<size && arr[leftNodeIndex]>arr[maxIndex]){//leftNodeIndex防止越界
            maxIndex = leftNodeIndex;
        }
        if (rightNodeIndex<size && arr[rightNodeIndex]>arr[maxIndex]){
            maxIndex = rightNodeIndex;
        }
        //调换位置
        if (maxIndex != index){
            int t = arr[maxIndex];
            arr[maxIndex] = arr[index];
            arr[index] = t;
            //调换之后可能影响下面的子树 不是大顶堆 再次调整
            toMaxHeap(arr,size,maxIndex);
        }
    }
}

面向对象

我的面向对象详解

异常

我的异常详解

Throwable(异常中顶级的父类)

Exception

编译时异常

运行时异常

  • 1/0 ClassNotFoun(类找不到)
  • NullPoint(空指针异常)
  • UnKnownType(未知的类型转换)
  • ArrayIndexoutofBoundsException(下标越界异常)
  • ……

Error

1.AWT错误
2.JVM错误

  • StackOverflow(栈溢出)
  • OutOfMemory(Java内存溢出)

五个关键字处理异常

  1. try{}
  2. catch(){}
    先小后大
  3. finally{}
  4. throw
    手动抛出异常
  5. throws
    方法抛出异常
    假如使用这个抛出异常,则虚拟机执行的中断处理后面的代码就不运行了,所以不推荐

自定义异常

继承Exception类即可

常用类

Object类

toString()

没有重写这个方法 就会默认打印对象地址

 		Person p = new Person("张三",18);
        String s = p.toString();
        System.out.println(s);//com.demo.Object.Person@75412c2f | Person{name=张三 ,age=18}

        //直接打印对象的名字,其实就是调用对象的toString  p=p.toString();
        System.out.println(p);//com.demo.Object.Person@5f150435 | Person{name=张三 ,age=18}
重写toString()

可以一键重写

@Override
public String toString() {
    return "Person{" +
            "name='" + name + '\'' +
            ", age=" + age +
            '}';
}

equals()

boolean equals(Object obj) 指示其他某个对象是否与此对象“相等”。
equals方法源码:

public boolean equals(Object obj) {
	return (this == obj);
}

参数:

  • Object obj:可以传递任意的对象
  • == 比较运算符,返回的是一个布尔值 true false
  • 基本数据类型:比较的是值
    引用数据类型:比较的是两个对象的地址值
  • this是谁?哪个对象调用的方法,方法中的this就是那个对象;p1调用的equals方法所以this就是p1
  • obj是谁?传递过来的参数p2
    this==obj ->p1==p2
重写equals()
@Override
    public boolean equals(Object obj) {
        //增加一个判断,传递的参数obj如果是this本身,直接返回true,提高程序的效率
        if(obj==this){
            return true;
        }

        //增加一个判断,传递的参数obj如果是null,直接返回false,提高程序的效率
        if(obj==null){
            return false;
        }

        //增加一个判断,防止类型转换一次ClassCastException
        if(obj instanceof Person){
            //使用向下转型,把obj转换为Person类型
            Person p = (Person)obj;
            //比较两个对象的属性,一个对象是this(p1),一个对象是p(obj->p2)
            boolean b = this.name.equals(p.name) && this.age==p.age;
            return b;
        }
        //不是Person类型直接返回false
        return false;
    }

当然也有一键重写 但是是和hashCode()一起的

hashCode()

clone()

getClass()

notify()

wait()

Math类

数学工具类

  1. public static double abs(double num):获取绝对值。有多种重载。
  2. public static double ceil(double num):向上【正方向】取整。
    Math.ceil(3.1) 打印得 4.0 Math.ceil(3.0) 得 3.0 如果是-3.1 得 -3
  3. public static double floor(double num):向下取整。
    Math.floor(30.9) 打印得 30.0
  4. public static long round(double num):四舍五入。

Math.PI代表近似的圆周率常量(double)。

Random类

随机数

System.out.println(new Random().nextInt(10));
//左闭合右开    [0,10)

File类

我的File类和各种流

包装类

别人的深入剖析Java中的装箱和拆箱

装箱与拆箱

  • 装箱:把基本类型的数据,包装到包装类中(基本类型的数据->包装类)
    • 构造方法:
      Integer(int value) 构造一个新分配的 Integer 对象,它表示指定的 int 值。
      Integer(String s) 构造一个新分配的 Integer 对象,它表示 String 参数所指示的 int 值。
      传递的字符串,必须是基本类型的字符串,否则会抛出异常 “100” 正确 “a” 抛异常
    • 静态方法:
      static Integer valueOf(int i) 返回一个表示指定的 int 值的 Integer 实例。
      static Integer valueOf(String s) 返回保存指定的 String 的值的 Integer 对象。
  • 拆箱:在包装类中取出基本类型的数据(包装类->基本类型的数据)
    • 成员方法:
      int intValue() 以 int 类型返回该 Integer 的值。
        //装箱:把基本类型的数据,包装到包装类中(基本类型的数据->包装类)
        //构造方法
        Integer in1 = new Integer(1);//方法上有横线,说明方法过时了
        System.out.println(in1);//1 重写了toString方法

        Integer in2 = new Integer("1");
        System.out.println(in2);//1

        //静态方法
        Integer in3 = Integer.valueOf(1);
        System.out.println(in3);

        //Integer in4 = Integer.valueOf("a");//NumberFormatException数字格式化异常
        Integer in4 = Integer.valueOf("1");
        System.out.println(in4);

        //拆箱:在包装类中取出基本类型的数据(包装类->基本类型的数据)
        int i = in1.intValue();
        System.out.println(i);

自动装箱和拆箱

自动装箱与自动拆箱:基本类型的数据和包装类之间可以自动的相互转换
JDK1.5之后出现的新特性
        /*
            自动装箱:直接把int类型的整数赋值包装类
            Integer in = 1; 就相当于 Integer in = new Integer(1);
         */
        Integer in = 1;
        /*
            自动拆箱:in是包装类,无法直接参与运算,可以自动转换为基本数据类型,在进行计算
            in+2;就相当于 in.intVale()【先把自己变成基本数据类型】 + 2 = 3
            in = in.intVale() + 2 = 3 又是一个自动装箱
         */
        in = in+2;
        ArrayList<Integer> list = new ArrayList<>();
        /*
            ArrayList集合无法直接存储整数,可以存储Integer包装类
         */
        list.add(1); //-->自动装箱 list.add(new Integer(1));
        int a = list.get(0); //-->自动拆箱  list.get(0).intValue();
    }

基本类型与字符串间的转换

  • 基本类型与字符串类型之间的相互转换
    • 基本类型->字符串(String)
    1. 基本类型的值+"" 最简单的方法(工作中常用)
    2. 包装类的静态方法toString(参数),不是Object类的toString() 重载
      static String toString(int i) 返回一个表示指定整数的 String 对象。
    3. String类的静态方法valueOf(参数)
      static String valueOf(int i) 返回 int 参数的字符串表示形式。
    • 字符串(String)->基本类型
    1. 使用包装类的静态方法parseXXX(“字符串”);
      Integer类: static int parseInt(String s)
      Double类: static double parseDouble(String s)
        //基本类型->字符串(String)
        int i1 = 100;
        String s1 = i1+"";
        System.out.println(s1+200);//100200

        String s2 = Integer.toString(100);
        System.out.println(s2+200);//100200

        String s3 = String.valueOf(100);
        System.out.println(s3+200);//100200

        //字符串(String)->基本类型
        int i = Integer.parseInt(s1);
        System.out.println(i-10);

        int a = Integer.parseInt("a");//NumberFormatException
        System.out.println(a);

Date类

别人的Date

Date

public class Demo{
	public static void main(String[] args){
		Date d1 = new Date();
        System.out.println(d1);//输出当前时间
        //Tue Jul 14 16:07:33 CST 2020
        System.out.println(d1.toLocaleString());
        //2020年7月14日 下午5:31:50
        
        Date d2 = new Date(0L);//将传入的参数(毫秒) 转换成时间格式
        System.out.println(d2);
        //Thu Jan 01 08:00:00 CST 1970

		Long l1 = d1.getTime();//把当前时间转换成毫秒
	}
}

SimpleDateFormat

构造方法
模式:区分大小写的
y 年
M 月
d 日
H 时
m 分
s 秒
写对应的模式,会把模式替换为对应的日期和时间
“yyyy-MM-dd HH:mm:ss”
注意:
模式中的字母不能更改,连接模式的符号可以改变
“yyyy年MM月dd日 HH时mm分ss秒”

	Date date = new Date();
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String s = formatter.format(date);//将date类型转换成构造方法格式的时间 并 生成字符串
    System.out.println(s);
    try {
        //调用SimpleDateFormat对象中的方法parse,把符合构造方法中模式的字符串,解析为Date日期
        //parse这个方法会出现异常
        Date d = formatter.parse(s);
        System.out.println(d);
    } catch (ParseException e) {
       	e.printStackTrace();
    }

Calendar(建议使用)

日历类

Calendar类是一个抽象类,里边提供了很多操作日历字段的方法(YEAR、MONTH、DAY_OF_MONTH、HOUR )
Calendar类无法直接创建对象使用,里边有一个静态方法叫getInstance(),该方法返回了Calendar类的子类对象
static Calendar getInstance() 使用默认时区和语言环境获得一个日历。

Calendar calendar = Calendar.getInstance();//多态
System.out.println(calendar);//不是地址 重写了toString方法的
get()

public int get(int field):返回给定日历字段的值。
其中的field是
int field:日历类的字段,可以使用Calendar类的静态成员变量获取 Calendar.XXX
public static final int YEAR = 1; 年
public static final int MONTH = 2; 月
public static final int DATE = 5; 月中的某一天
public static final int DAY_OF_MONTH = 5;月中的某一天
public static final int HOUR = 10; 时
public static final int MINUTE = 12; 分
public static final int SECOND = 13; 秒

        Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        System.out.println(year);

        int march = c.get(Calendar.MARCH) + 1;//get(Calendar.MARCH)范围是0-11
        System.out.println(march);
set()

public void set(int field, int value):将给定的日历字段设置为给定值。

		Calendar c = Calendar.getInstance();
		System.out.println(c.get(Calendar.YEAR));//系统当前年份
		c.set(Calendar.YEAR,2000);
        System.out.println(c.get(Calendar.YEAR));//2000
        
        c.set(2000,8,24);//一键设定年月日
add()

public abstract void add(int field, int amount):根据日历的规则,为给定的日历字段添加或减去指定的时间量。
把指定的字段增加/减少指定的值
参数:
int field:传递指定的日历字段(YEAR,MONTH…)
int amount:增加/减少指定的值
正数:增加
负数:减少

        Calendar c = Calendar.getInstance();
        //把年增加2年
        c.add(Calendar.YEAR,2);
        //把月份减少3个月
        c.add(Calendar.MONTH,-3);
getTime()

public Date getTime():返回一个表示此Calendar时间值(从历元到现在的毫秒偏移量)的Date对象。
把日历对象,转换为日期对象

        //使用getInstance方法获取Calendar对象
        Calendar c = Calendar.getInstance();

        Date date = c.getTime();
        System.out.println(date);

System类

currentTimeMillis()

public static long currentTimeMillis():返回以毫秒为单位的当前时间。

用来测试程序的效率

		//执行循环前获取一次时间
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            System.out.println(i);
        }
        //循环结束获取一次时间
        long end = System.currentTimeMillis();
        //差值就是循环耗的时间
        System.out.println(end-start);

arraycopy()

public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length):将数组中指定的数据拷贝到另一个数组中。
参数:
src - 源数组。
srcPos - 源数组中的起始位置(起始索引)。
dest - 目标数组。
destPos - 目标数据中的起始位置。
length - 要复制的数组元素的数量。
练习:
将src数组中前3个元素,复制到dest数组的前3个位置上
复制元素前:
src数组元素[1,2,3,4,5],dest数组元素[6,7,8,9,10]
复制元素后:
src数组元素[1,2,3,4,5],dest数组元素[1,2,3,9,10]

        int[] src = {1, 2, 3, 4, 5};
        int[] dest = {6, 7, 8, 9, 10};
        System.arraycopy(src,0,dest,0,3);
        System.out.println(Arrays.toString(dest));

String类

我的String详解
不可变性 final
推荐使用情况
操作量教少

StringBuilder

可变
推荐使用情况
单线程数据量较大 效率高 不安全

与String比较

String类

  1. 字符串是常量,创建之后是不能改变的:是指创建了一个字符串"a"那么这个a就不能变成别的 他会一直存在 没用了就等着回收
  2. 字符串的底层是一个被final修饰的数组,不能改变,是一个常量
    private final byte[] value;

进行字符串相加,内存中就会有多个字符串,效率低下 如
String s = “a” + “b” + “c”; 这样之后就会出现5个字符串
a b c ab abc 这5个


StringBuilder类

  1. 也叫字符串缓存区,可以提高字符串操作效率(看成一个长度可以变化的字符串)
  2. 底层也是一个数组,但是没有被final修饰,可以改变长度
    byte[] value = new byte[16];
  3. StringBuilder在内存中始终是一个数组,占用空间少,效率高
    如果超过了StringBuilder的容量,会自动扩容

进行字符串相加,始终是一个数组

StringBuilder构造方法:

    StringBuilder() 构造一个不带任何字符的字符串生成器,其初始容量为 16 个字符。
    StringBuilder(String str) 构造一个字符串生成器,并初始化为指定的字符串内容。
		//空参数构造方法
        StringBuilder bu1 = new StringBuilder();
        System.out.println("bu1:"+bu1);//bu1:""

        //带字符串的构造方法
        StringBuilder bu2 = new StringBuilder("abc");
        System.out.println("bu2:"+bu2);//bu2:abc

append()

public StringBuilder append(…):添加任意类型数据的字符串形式,并返回当前对象自身。

public static void main(String[] args) {
        //创建StringBuilder对象
        StringBuilder bu = new StringBuilder();
        //使用append方法往StringBuilder中添加数据
        //append方法返回的是当前对象本身 就是返回 bu的地址
        //StringBuilder bu2 = bu.append("abc");//把bu的地址赋值给了bu2
        //System.out.println(bu);//"abc"
        //System.out.println(bu2);//"abc"
        //System.out.println(bu==bu2);//比较的是地址 true

        //使用append方法无需接收返回值
//        bu.append("abc");
//        bu.append(1);
//        bu.append(true);
//        bu.append(8.8);
//        bu.append('中');
//        System.out.println(bu);//abc1true8.8中

        /*
            链式编程:方法返回值是一个对象,可以继续调用方法
         */
        "abc".toUpperCase().toLowerCase().toUpperCase().toLowerCase();
        //字符串调用切换大小写 返回值还是字符串
        bu.append("abc").append(1).append(true).append(8.8).append('中');
        //append的返回值也还是StringBuilder对象
        System.out.println(bu);//abc1true8.8中

    }

reverse()

        StringBuilder bu = new StringBuilder("abc");
        bu.reverse();
        System.out.println(bu);//cba

toString()

StringBuilder和String可以相互转换:

  • String->StringBuilder:可以使用StringBuilder的构造方法
    StringBuilder(String str) 构造一个字符串生成器,并初始化为指定的字符串内容。
//String->StringBuilder
        String str = "hello";
        System.out.println("str:"+str);
        StringBuilder bu = new StringBuilder(str);
  • StringBuilder->String:可以使用StringBuilder中的toString方法
    public String toString():将当前StringBuilder对象转换为String对象。
//StringBuilder->String
        String s = bu.toString();
        System.out.println("s:"+s);

StringBuffer

可变长 append()
推荐使用情况
多线程数据量较大 效率低安全

集合框架

自己的集合

IO流

我的File类和各种流
在这里插入图片描述
详细代码在eclipse中
别人的IO流 详解

多线程

我的多线程初级

Lambda

我的Lambda初级

网络编程

网络编程初

函数式接口

Stream流

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值