Java内存划分初识:
Java程序执行的时候,会将内存分为栈空间、堆空间
栈空间特点 :
1,自动分配,不需要程序员申请
2,栈空间存取数据的效率较高
3,栈空间的数据 按照 先进后出的方式管理
4,栈空间存储空间较小,不能存放太多的数据
5,JVM将基本类型的数据存放在栈空间
堆空间特点 :
1,需要程序员申请,通过new关键字申请
2,堆中存取效率相对较低
3,堆空间中存放数据是随机分配位置,所以在申请了空间后,会得到一个地址值,指向变量
4,堆空间存放数据的空间比较到,能存放大量的数据
5,引用类型的数据一般都存放在堆空间中
方法
Java是面向对象的语言,对象都会有一些方法,方法其实就是这些类可以做的事情,也称为函数
方法中,一般都会写一些执行了某些功能的代码
将来可以调用这个方法,从而去完成某些想要的功能
方法一般单独声明于类中
语法:
修饰符 返回值类型 方法名 (参数列表){
代码块;
return 返回值;
}
修饰符 : 暂时的写法 public static
返回值类型 :可以是void ,表示没有返回值 ,也可以是数据类型(基本类型和引用类型)
方法名 : 自己取的名字,遵循标识符命名规范
参数列表 :将来调用这个方法时候,是否需要传入值进行运算,如果不需要,可以不写
参数的定义方式 : 数据类型 变量名
代码块 : 将来方法中执行的功能
return :跟返回值类型挂钩
如果有返回值类型,那么就需要return 对应类型的值,
如果没有返回值类型,return可以省略
形参 :定义在方法体的括号中的参数
实参 :调用方法的时候,传入的实际的内容
public class MethodDemo {
//写一个方法,调用之后,可以传入2个整数,并完成两个整数的计算求和后返回
public static int add(int a,int b){
int sum = a + b; //拿到传入的参数,并计算和
return sum; //把求和的结果返回
}
public static void main(String[] args) {
//调用方法,
//也可以将整个方法的表达式参与运算
System.out.println(add(10, 20));
// 可以声明一个变量,接收返回的值
int result = add(10,20);
System.out.println(result);
}
}
//方法的其他用法
public class MethodDemo02 {
public static void main(String[] args) {
//修饰符 返回值 方法名 (参数列表){
// 代码块;
// return;
// }
add();
//调用方法,传入参数的类型不能有错
add("hello","world");
//调用有返回值的方法
//1,要么将方法结果返回给一个变量
//2,要么将返回值结果,拿过来做运算
String s = addString();
System.out.println(addString());
//调用有参数有返回值的方法
String s3 = addString("你好", "世界");
String s1 = "你好";
String s2 = "世界";
String s4 = addString(s1, s2);
System.out.println(s3);
System.out.println(s4);
}
// 没有返回值的方法,一般在方法中,会把要做的事情处理完
//1,没有返回值,没有参数 ,某些固定的功能,不需要改变的时候使用这种
public static void add(){
String s1 = "hello";
String s2 = "world";
System.out.println(s1 + s2);
}
//2,没有返回值,有参数的情况,一般会根据用户传入的内容,执行对应的功能
public static void add(String s1,String s2){
System.out.println(s1 + s2);
}
//3,有返回值,没有参数的情况
public static String addString(){
//只要有返回值,必须对应有return
String s1 = "hello";
String s2 = "world";
//返回字符串的拼接
return s1+s2;
}
//4,有返回值,有参数的情况
public static String addString(String s1,String s2){
return s1 + s2;
}
//形参 :定义在方法体的括号中的参数
// 实参 :调用方法的时候,传入的实际的内容
}
定义一个方法,调用的时候传入两个整数,传入之后,让两个参数的值做交换后打印输出
输出内容 : 传入的参数为 a = ? b = ? , 交换之后的a = ? b = ?
public static void swap(int a , int b){
System.out.println("传入的参数为 a = " + a + " ,b = " + b);
int c = a;
a = b;
b = c;
System.out.println("交换之后的 a = " + a + " ,b = " + b);
}
方法递归
方法递归其实就是方法在自己的方法体中调用自身
递归在调用的时候,可能会产生栈溢出错误,使用的时候要注意控制递归的次数,而且将来要去指定递归结束的条件。
//方法递归的使用
public class MethodDemo03 {
public static void main(String[] args) {
//方法递归
//method01();
int sum = sum01(100);
System.out.println(sum);
int sum02 = sum02(100);
System.out.println(sum02);
}
//public static void method01(){
// int i = 1;
// System.out.println(++i);
// method01();
//}
//定义一个方法,传入参数n,可以返回1-n之间数值的和
//普通循环求法
public static int sum01(int n){
int sum = 0;
for (int i = 0; i <= n; i++) {
sum += i;
}
return sum;
}
//递归的写法 1+2+3+4+5+...+n
public static int sum02(int n){
if (n == 1){
return 1;
}
return n + sum02(n-1);
}
// n = 1 sum = 1
// n = 2 2 + sum02(1) ==> 2 + 1
// n = 3 3 + sum02(2) => 3 + 2 + 1
//..
}
public class Test2 {
//一只青蛙一次可以跳上一级台阶,也可以跳上两级台阶。
//求该青蛙跳上一个n级的台阶总共有多少种跳法
public static int frog(int n){
if (n == 1 || n == 2){
return n;
}
return frog (n-1) + frog ( n - 2);
}
public static void main(String[] args) {
System.out.println(frog(11));
}
}
数组
数组的定义
数组其实也是声明的一个变量,跟普通的变量不同的是,可以存储相同数据类型的一组数据
数组是一个长度固定的数据结构,数组也是一个对象(引用数据类型)
数组的声明方式
语法 :
步骤1: 先声明数组
1,数据类型 变量名[];
2,数据类型[] 变量名;
步骤2: 给数组声明空间
数组名 = new 数组数据类型[数组长度];
示例:
int[] array ; 或者 int array[];
array = new int[10];
合并写法 : int[] array = new int[10];
步骤3: 给数组的空间赋值 ,分配空间,通过数组的索引下标找到对应的空间
array[0] = 10;
//数组的声明
public class Demo01 {
public static void main(String[] args) {
//数组声明:
// 写法1
//创建数组,并声明空间,赋值给变量arr
int[] arr = new int[5];
//给数组空间赋值
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
arr[3] = 40;
arr[4] = 50;
//写法2:已知数组的内容。可以简写
int[] arr1 = new int[]{10,20,30,40,50};
//写法3 : 再简写
int[] arr2 = {10,20,30,40,50};
//使用写法1,声明一个String类型的数组,数组中有5个空间,内容随便写
String[] strArray = new String[5];
strArray[0] = "hello";
strArray[1] = "world";
strArray[2] = "java";
strArray[3] = "mysql";
strArray[4] = "linux";
//使用写法3,声明一个char类型的数组,数组有5个char类型的值
char[] charArray = {'a','b','c','d','e'};
}
}
数组的特征(长度、索引)
长度固定,索引下标从0开始 ,下标的值是 从 0 ~ 长度-1
数组的遍历(循环遍历)
public class Demo02 {
public static void main(String[] args) {
int[] arr = {10,20,30,40,50};
//直接输出数组,输出的是数组变量的引用地址
System.out.println(arr);
//通过数组下标,将它的值输出
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[3]);
System.out.println(arr[4]);
System.out.println("------------------------");
//使用for循环遍历
//循环的次数 : 跟数组的长度一致
for (int i = 0; i < 5; i++) {
System.out.println(arr[i]);
}
System.out.println("------------------------");
//数组中,有一个length属性,可以返回数组的长度
System.out.println(arr.length); //5
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
//增强for循环完成数组的遍历
//for(数据类型 变量 : 数据集合){
//}
System.out.println("------------------------");
for (int i :arr){
System.out.println(i);
}
//快捷键 :itar
for (int i = 0; i < arr.length; i++) {
int i1 = arr[i];
System.out.println(i1);
}
//iter
for (int i : arr) {
System.out.println(i);
}
}
//定义一个方法,调用方法的时候,可以传入一个数组,
// 然后这个方法可以将数组的内容输出
public static void printArray(int[] arr){
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
}
数组的内存分配
1,int[] arr = new int[5] : 表示在内存的堆区申请一个空间,这个空间有5个位置,每个位置的默认值是0,然后将这个区域在内存中的地址,指向变量 arr
2,arr[0] = 10 ; 表示通过 arr对应的地址引用,找到内存中数组的位置空间,通过下标0,找到这个空间中对应下标的值,然后将10 替换掉原有的默认值
二维数组的创建和遍历
public class Demo05 {
public static void main(String[] args) {
//创建二维数组
//创建格式 :
//格式1:
//数据类型[][] 数组名 = new 数据类型[m][n]
//格式2:
// 数据类型[][] 数组名 = {{...},{...},{...}};
//
// 有个5个班级,各有5个学生数学课成绩
//将所有班级,所有学生的数学成绩录入,
//录入后,求5个班各自的总成绩
Scanner scanner = new Scanner(System.in);
//定义数组
int[][] array = new int[5][5];
//使用嵌套for循环完成成绩的录入
//i 班级 j 学生
for (int i = 0; i < 5; i++) {
System.out.println("第" + (i+1) + "个班:");
for (int j = 0; j < 5; j++) {
System.out.println("第" + (j+1) + "个学生的成绩:");
array[i][j] = scanner.nextInt();
}
}
//统计成绩:
for (int i = 0; i < array.length; i++) {
int total = 0; //记录总成绩
for (int j = 0; j < array[i].length; j++) {
//拿到每个班的学生的成绩做累加
total += array[i][j];
}
System.out.println("第" + (i+1) + "个班级的总成绩是:" + total);
}
}
}
基本算法
排序方法
冒泡排序
- 比较相邻的元素。如果第一个比第二个大,就交换它们两个;
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
- 针对所有的元素重复以上的步骤,除了最后一个;
- 重复步骤1~3,直到排序完成
-
/* 冒泡排序 */ public class BubbleSort { public static void main(String[] args) { //声明一个数组, //排序是为了将数组中的数据按照顺序从小到大排列 int[] arr = {25,36,11,5,2}; System.out.println("排序前"); printArray(arr); /* //第一次排序 for (int i = 0; i < arr.length - 1; i++) { //将数组的值做两两比较 if (arr[i] > arr[i+1]){ //交换 int temp= arr[i]; arr[i] = arr[i+1]; arr[i+1] = temp; } } System.out.println("第一次排序完:"); printArray(arr); //第二次排序 25 11 5 2 36 for (int i = 0; i < arr.length-1-1 ; i++) { //将数组的值做两两比较 if (arr[i] > arr[i+1]){ //交换 int temp= arr[i]; arr[i] = arr[i+1]; arr[i+1] = temp; } } System.out.println("第二次排序完:"); printArray(arr); //第三次排序 for (int i = 0; i < arr.length-1-1-1 ; i++) { //将数组的值做两两比较 if (arr[i] > arr[i+1]){ //交换 int temp= arr[i]; arr[i] = arr[i+1]; arr[i+1] = temp; } } System.out.println("第三次排序完:"); printArray(arr); //第四次排序 for (int i = 0; i < arr.length-1-1-1-1 ; i++) { //将数组的值做两两比较 if (arr[i] > arr[i+1]){ //交换 int temp= arr[i]; arr[i] = arr[i+1]; arr[i+1] = temp; } } System.out.println("第四次排序完:"); printArray(arr); for (int i = 0; i < arr.length -1 ; i++) { //外层循环控制总次数 for (int j = 0; j < arr.length-i-1 ; j++) { if (arr[j] > arr[j+1]){ int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } }*/ bubbleSort(arr); System.out.println("排序完:"); printArray(arr); } //定义一个冒泡排序的方法: public static void bubbleSort(int[] arr){ for (int i = 0; i < arr.length -1 ; i++) { //外层循环控制总次数 for (int j = 0; j < arr.length-i-1 ; j++) { if (arr[j] > arr[j+1]){ int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } } public static void printArray(int[] arr){ for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println(); } }
选择排序
-
//选择排序 public class SelectSort { public static void main(String[] args) { int[] arr = {33,12,4,56,23,44,74,3}; System.out.println("排序前:"); printArray(arr); selectSort(arr); System.out.println("排序完:"); printArray(arr); } //输出方法 public static void printArray(int[] arr){ for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println(); } //写一个选择排序方法 public static void selectSort(int[] arr){ //存在一个有序区和无序区 //排序开始之前,有序区没有内容 //第一次排序的时候,将第一个数值标记为有序的第一个值 for (int i = 0; i < arr.length - 1; i++) { //指定一个最小数值的索引 int minIndex = i; //从有序区的后面的第一个(i+1)开始遍历 for (int j = i+1; j < arr.length ; j++) { //找到最小的值 if (arr[j] < arr[minIndex]){ //将最小值的下标做交换 minIndex = j; } } //循环之后,做数据交换 if (i != minIndex){ int temp = arr[i] ; arr[i] = arr[minIndex]; arr[minIndex] = temp; } } } }
插入排序
- 从第一个元素开始,该元素可以认为已经被排序;
- 取出下一个元素,在已经排序的元素序列中从后向前扫描;
- 如果该元素(已排序)大于新元素,将该元素移到下一位置;
- 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
- 将新元素插入到该位置后;
- 重复步骤2~5。
-
public class InsertSort { public static void main(String[] args) { int[] arr = {33,12,4,56,23,44,74,3}; System.out.println("排序前:"); printArray(arr); //排序 insertSort(arr); System.out.println("排序完:"); printArray(arr); } //输出方法 public static void printArray(int[] arr){ for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println(); } //插入排序方法 public static void insertSort(int[] arr){ //第一次循环从第二个元素开始,默认第一个元素是有序的 for (int i = 1; i < arr.length; i++) { //指定一个插入数 int insertNum = arr[i]; //指定一个已经排序好的元素的个数 int j = i - 1; //循环判断 //如果插入的值,小于前面的有序区的最后一个值(arr[j]), //把有序区的最后一个值往后移动, //然后再和最后一个值前面的值(arr[j-1])作比较,所以, //循环的时候,需要做j-- 操作 while ( j >= 0 && arr[j] > insertNum){ arr[j+1] = arr[j]; j--; } arr[j+1] = insertNum; } } }