P1_Java基础语法

文章目录


不断整理和完善。加油。

参考:
尚硅谷宋红康
狂神说
csdn博客

版本1:2021.12.9 ----> 规范整理,内容清理

一、常用Dos命令

#ping命令
ping www.baidu.com

#盘符切换  D:
#查看当前目录下的所有文件    dir
#切换目录        cd change directory
#返回上级目录     cd..
#清理屏幕  cls  (clear screen)
#退出终端  exit
#查看电脑的ip     ipconfig	

二、IDE设置

快捷命令/操作

sout System.out.println();
psvm public static void main(String[] args)

Ctrl + Alt + L代码格式化,更加规范
Alt+Enter用于代码补全,修正错误
ALT + SHIFT + /多行注释
ALT + /单行注释
文档注释

Generate 生成构造方法、生成get()和set()方法等等
ALT + Insert 生成构造方法、get()和set()方法、重写toString()方法等
.var 智能补齐
CTRL + ALT + M选中代码,提取为方法

arr.fori使用for循环快捷键
iter增强for循环快捷键

常用设置

字体设置

Preferences / Settings | Editor | Font ,字体推荐使用 JetBrains Mono ,字体大小建议 16/18,根据个人需要选择是否需要开启连字。

显示方法分隔线

勾选上 Preferences / Settings | Editor | General | Appearance 下的 Show method separators

忽略大小写设置(推荐!!)
在这里插入图片描述

恢复默认布局(自己把窗口布局弄乱了)

Window------>Restore Default Layout

使用主题,更改代码配色
注:安装主题插件后,忘了在这里设置,以为不生效。
在这里插入图片描述
单行显示多个Tabs

File–>settings–>Editor–>General -->Editor Tabs去掉√ Show tabs in one row

配置类文档注释信息和方法注释模版

推荐参照配置:IntelliJ IDEA设置方法注释模板并解决入参和返回值为空问题

/**
 * @description 查询要素权限的接口
 * @author Lemonade 
 * @param: userId
 * @updateTime 2021/12/9 下午4:56 
 * @return: grp.pt.core.ResultData<grp.frame.model.po.UserPo>
 */

全局设置 SDK

File -> New Projects Setup -> Structure Project 下的 Project SDK 选项,将其更改为你最常用的 Java 版本。

插件推荐

Rainbow Brackets : 彩虹括号
使用各种鲜明的颜色来展示你的括号,效果图如下。可以看出代码层级变得更加清晰了,可以说非常实用友好了!
Tabnine:基于 AI 的代码提示
Tabnine 这个插件用于智能代码补全,它基于数百万 Java 程序,能够根据程序上下文提示补全代码。Tabnine 和 IDEA 自带的智能提示两者互补。


三、Java概述

JVM、JRE和JDK的关系

JVM
Java Virtual Machine是Java虚拟机,Java程序需要运行在虚拟机上,不同的平台有自己的虚拟机,因此Java语言可以实现跨平台。

JRE
Java Runtime Environment包括Java虚拟机和Java程序所需的核心类库等。核心类库主要是java.lang包:包含了运行Java程序必不可少的系统类,如基本数据类型、基本数学函数、字符串处理、线程、异常处理类等,系统缺省加载这个包

如果想要运行一个开发好的Java程序,计算机中只需要安装JRE即可。

JDK
Java Development Kit是提供给Java开发人员使用的,其中包含了Java的开发工具,也包括了JRE。**所以安装了JDK,就无需再单独安装JRE了。**其中的开发工具:编译工具(javac.exe),打包工具(jar.exe)等

JVM&JRE&JDK关系图
在这里插入图片描述

什么是跨平台性?原理是什么?

所谓跨平台性,是指java语言编写的程序,一次编译后,可以在多个系统平台上运行。
实现原理:Java程序是通过java虚拟机在系统平台上运行的,只要该系统可以安装相应的java虚拟机,该系统就可以运行java程序。

JAVA语言有哪些特点

简单易学(Java语言的语法与C语言和C++语言很接近)
面向对象(封装、继承、多态)
平台无关性(Java虚拟机实现平台无关性)
支持网络编程并且很方便(Java语言诞生本身就是为简化网络编程设计的)
支持多线程(多线程机制使应用程序在同一时间并行执行多项任务)
健壮性(Java语言的强类型机制、异常处理、垃圾的自动收集等)
安全性

Java和C++的区别

  • 都是面向对象的语言,都支持封装、继承和多态
  • Java不提供指针来直接访问内存,程序内存更加安全
  • Java的类是单继承的,C++支持多重继承;虽然Java的类不可以多继承,但是接口可以多继承。
  • Java有自动内存管理机制,不需要程序员手动释放无用内存

四、用户交互Scanner

通过Scanner类来获取用户输入

import java.util.Scanner;

//创建一个扫描器对象,用于接收键盘输入
Scanner sc = new Scanner(System.in);

//使用next方式接收:以空格作为分隔符
String str = sc.next();
System.out.println("输出的内容为:" + str);
//hello world
//输出的内容为:hello

//使用nextLine方式接收:以回车enter作为分隔符
String aa = sc.nextLine();                            //接收字符串
System.out.println("输出的内容为:" + aa);
//hello world
//输出的内容为:hello world

int x = sc.nextInt();                                 //接收整数

//凡是属于I/O流的类如果不关闭会一直占用资源,要养成好习惯用完就关掉
Scanner.close();
三步走:

 - 导包 (IDEA可以忽略这一步)
import java.util.Scanner;
 - 创建对象
Scanner sc = new Scanner(System.in);
 - 接收从键盘录入的数据
int x = sc.nextInt();

一般为了方便使用,应该加上提示键盘输入的输出语句

五、关键字、标识符、注释、常量

关键字

被赋予特定含义的单词

在这里插入图片描述
在这里插入图片描述

标识符(常见命名规则)(Identifier)

  • 包:全部小写,域名反转比如 com.cskaoyan
  • 类和接口:每个单词首字母大写 UserEleValueController
  • 方法或变量:第一个单词小写,其余单词首字母大写。比如 studentName
  • 常量:全部大写,单词之间下划线分隔。比如 MAX_NUM

注释(comment)

单行注释、多行注释、文档注释

常量(constant)

概述:程序运行过程,值不能发生改变的量。分为字面值常量和自定义常量。

整数常量:

  • 二进制:以0b开头,比如0b10011010
  • 八进制:以0开头,比如06752324561
  • 十进制:默认十进制
  • 十六进制:以0x开头,比如0x8c631d

有符号数表示法:原码、反码和补码。整数在计算机中的存储和计算都是以补码的形式进行

六、变量、数据类型、转换

6.1 变量(variable)

使用前先声明,然后赋值(初始化),才能使用。

6.2 数据类型

6.2.1 Java有哪些数据类型

定义:Java是强类型语言,对于每一种数据都定义了明确的具体的数据类型,在内存中分配了不同大小的内存空间。
分类
在这里插入图片描述
Java基本数据类型图
在这里插入图片描述

引用数据类型(reference)
字符串(String)是一种引用数据类型
String属于引用数据类型中的类

6.2.2 基本数据类型的数据类型转换(conversion)
(1)自动类型转换(automatic)
  • byte、short、char之间不互相转换,一旦之间发生运算,一律自动转换为int进行运算,结果是int
  • byte、short、char任一数据类型与int进行计算,一律自动转换为int进行计算,结果是int
  • byte、short、char、int任一数据类型与long进行计算,一律自动转换为long进行计算,结果是long
  • byte、short、char、int、long任一数据类型与float进行计算,一律自动转换为float进行计算,结果是float
  • byte、short、char、int、long、float任一数据类型与double进行计算,一律自动转换为double进行计算,结果是double

以下图中,实线虚线都表示可以发生自动类型转换

  • 实现表示不会有精度问题
  • 虚线表示可能会产生精度丢失
    在这里插入图片描述
(2)强制类型转换(cast)
6.2.3 最有效率的方式计算2乘以8

2<<3(左移3位相当于乘以2的3次方,右移3位相当于除以2的3次方)。

6.2.4 Math.round(11.5)等于多少?Math.round(-11.5)等于多少?

Math.round(11.5)的返回值是 12,Math.round(-11.5)的返回值是-11。四舍五入的原理是在参数上加 0.5 然后进行下取整。

6.2.5 float f=3.4;是否正确

不正确。3.4 是双精度数,将双精度型(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换float f =(float)3.4或者写成 float f =3.4F

6.2.6 short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗

对于 short s1 = 1; s1 = s1 + 1;由于 1 是 int 类型,因此 s1+1 运算结果也是 int型,需要强制转换类型才能赋值给 short 型。
而 short s1 = 1; s1 += 1;可以正确编译,因为 s1+= 1;相当于 s1 = (short(s1 + 1);其中有隐含的强制类型转换

七、运算符(operator)、操作数

A 算术运算符(arithmetic)+ - * / %取余 ++自增 --自减

  1. 舍入规则:四舍五入?向下取整?向上取整?都不是,Java中是向0方向取整
    如果想得到小数,应该乘以1.0,变成double类型,比如9*1.0 / 4
比如
7 / 2 = 3.5 = 3(向0的方向取整)
-9 / 2 = -4.5 = -4(向0取整)
  1. ++和–
int a = 4;
int b = (a++)+(++a)+(a * 10);       //结果是4 + 6 + (6 * 10)= 70
结果是a = 6;b = 70;
int a = 3;
a = a++;
a = a++;      //结果a还是等于3(原因如下:先参与运算,再+1)

a++实际过程是
int temp = a;
a++;
a = temp;

在这里插入图片描述

在这里插入图片描述

B 赋值运算符(assignment)= += -= *= /= %=

int x = 0;
x = x + 3.5;   //error   int x1 = x + 3.5;

int x = 0;
x += 3.5     //ok

扩展赋值运算符隐含强转,仍然可能发生精度丢失
x += y <----> x = (x的数据类型) (x + y)

C 关系运算符(comparison)== != < > <= >= instanceof

  1. intanceof使用方法是 s instanceof String 判断s能否被String类型接收
  2. 比较运算符==不能误写成=
  3. &&和||相对于&和|具有短路效应,在实际开发中,一般使用&&和||,因为可以降低运算量,提高效率。
  4. 精度问题,浮点数进行比较判断,不能使用==

D 逻辑运算符(logical)&与 |或 !非 ^异或 &&短路与 ||短路或

  1. 在Java中不能写成3 < x < 6,应该写成x > 3&& x<6;
  2. 异或^,两边不同才为true

专门用于boolean类型进行计算的运算符,结果也为boolean

boolean a = true;
boolean b = false;

System.out.println(a & b);//   与

有些书籍里,不把&和 |列入逻辑运算符中,而是直接称之为位运算符
实际开发,&&、||、!最常用

E 位运算符(shift,了解)<<左移 >>右移 >>>无符号右移 &按位与 |按位或 ^按位异或 ~按位取反

位运算符是直接对二进制进行操作的,所以效率很高
位运算符是直接对整数的二进制位进行计算的运算符

  1. 左移<<:低位补0,高位丢弃。左移1位相当于乘以2
比如int a = 64;  a << 2;//左移两个单位
0000 0000,0000 0000,0000 0000,0100 0000    64
0000 0000,0000 0000,0000 0001,0000 0000    256
  1. 右移>>:被移位的二进制最高位是0,右移后高位空缺补0;若最高位是1,则最高位补1
  2. 无符号右移>>>:空缺位直接补0

练习

问题1:如何用位运算来判断一个数是否是奇数?

解析:奇数的二进制最后一位必定是1,只需要和 1 进行 & 的位运算即可,结果为1则奇数。
public static void main(String[] args) {
        //位运算判断一个数是否是奇数
        int a = 2022;
        //System.out.println(a % 2 != 0);
        System.out.println((a & 1) == 1);
    }
    
结果:false

问题2:对2的n次幂取余数,可以转换为位运算

问题3:判断一个数是否是2n

解析:判断a & (a - 1) == 0 是否成立;(常规做法:循环判断是否可被2整除,直到等于1)
原理:2的整数次幂只有一位是1
public static void main(String[] args) {
        int a = 65536;
        System.out.println((a & (a -1)) == 0 );
    }

问题4:请自己实现2个整数变量的交换

问题5:一个数组中只有1个数出现1次,其余的数都出现2次,找出这个数

方法1:
方法2(重要):把只出现1次的数记为a,将数组中所有元素进行异或操作,相同的数异或为0,可得结果为a值。

问题6:用最有效率的方式计算2 * 8的结果

2 * 8 = 2<<3 = 16,即2左移3位

F 三目运算符(ternary) 关系表达式 ? 表达式1:表达式2

关系表达式值为true,取表达式1值;否则取表达式2值
最大的特点是它一定会执行一个表达式。

问题1:获取3个整数中的最大值。

方法1:先取a和b之中的最大值,再和c比较
方法2:嵌套使用3目运算符(不推荐,程序可读性差)
int a = 10;
int b = 20;
int c = 30;

//方式1:先获取a,b的较大值temp,再获取temp和c的较大值
int temp = a > b ? a : b;
int max = temp > c ? temp : c;
System.out.println("max = " + max);

//方式2:把1用嵌套的形式写出来
int max = (a > b ? a : b) > c ? (a > b ? a : b) : c;
System.out.println("max = " + max);

//方式3:先比较a和b。
//a大,比较a和c,否则,比较b和c

问题2:比较2个整数是否相同,相同返回true,否则返回false

a == b ? true : false//没必要
直接输出boolean b = (a == b) 即可

问题3:比较4个整数的大小,直接嵌套过于繁琐,所以两两比较。

八、访问修饰符(public、private、protected、default)

访问修饰符 public,private,protected,以及不写(默认default)的区别

Java中,可以使用访问修饰符来保护对类、变量、方法和构造方法的访问。Java 支持 4 种不同的访问权限,如下

  • private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
  • default (即缺省,什么也不写,不使用任何关键字): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法
  • protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
  • public : 对所有类可见。使用对象:类、接口、变量、方法
    在这里插入图片描述

九、流程控制

9.1 顺序结构

9.2 选择结构(Selective Structure)

实际上开发中,90%以上的情况都在使用if而不是switch

if语句

强烈建议:无论statement是一句还是多句,都不要省略大括号
建议能够选择三目运算符的场景,选择三目运算符。但是实际使用较少(刷算法题)

1.单分支if
2.双分支if

3.多分支if

(多分支if)每个condition都不满足,执行最后的else
充分考虑用户的输入(如非法输入),并提示

if(condition1){
	statement1
} else if (condition2){
	statement2
} .... else {
 	statement
}
switch语句

警告:实际开发中,我们从不使用使用switch语句。(Java核心技术 卷1)

switch(expression){
    case value1:{
    	statement1;
    	break;
    }
    
    case value2:
    statement2;
    break;
    ...    
   	default:
    statement;
    break;
}

case标签可以是:

  • 类型为char、byte、short、int的常量表达式
  • 枚举常量
  • 还可以是字符串字面量(Java SE7开始)

case穿越:(一年十二月 分为四个季度)

  • 当省略掉某个case中的break后,statement就会按照顺序一直被执行
  • 这个时候statement的执行不仅限于自身case了,这个过程会持续到switch结束或者碰到一个break

9.3 循环结构

实际开发中,优先考虑for循环,再选while,最后才是do…while
如果循环次数很明确,使用for循环。否则使用while比较方便(并不是不能用for)

for循环(增强for)
for(初始化语句 ; 条件判断语句(布尔表达式); 循环控制语句) {
  //循环体语句  
}
// 对数据库中查询到的数据进行分类:角色权限和用户权限
for (UserEleValuePo userEleValuePo : userEleValuePos) {
    if (!"0".equals(userEleValuePo.getRoleId())) {
        userEleValuePos1.add(userEleValuePo);
    } else {
        userEleValuePos2.add(userEleValuePo);
    }
}
while循环
初始化语句;
while(条件判断语句){
  循环体语句;
  (循环控制语句)
}
do…while循环
初始化语句;
do{
    循环体语句;
    (循环控制语句)
} while(条件判断语句);

代码块

代码块的最大作用,在于限制变量的作用域
代码块中定义的变量,在代码块外不能生效,这种变量称之为”局部变量“

break,continue,return的区别及作用

break跳出总上一层循环,不再执行循环(结束当前的循环体)
continue跳出本次循环,继续执行下次循环(结束正在执行的循环 进入下一个循环条件)
return程序返回,不再执行下面的代码(结束当前的方法 直接返回)

public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            if (i == 3) {
                System.out.println("我喜欢学习Java!");
                //填入
                break;
                //continue;
                //return;
            }
            System.out.println(i);
        }
        System.out.println("我喜欢学习C++!");
    }
break运行效果:

0
1
2
我喜欢学习Java!
我喜欢学习C++!
continue运行效果:

0
1
2
我喜欢学习Java!
4
我喜欢学习C++!
return运行效果:

0
1
2
我喜欢学习Java!

如何跳出当前的多重嵌套循环(带标签的break语句)

在Java中,要想跳出多重循环,可以在外面的循环语句前定义一个标号比如ok,然后在里层循环体的代码中使用带有标号的break 语句,即可跳出外层循环。例如:

public static void main(String[] args) {
    ok:
    for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 10; j++) {
            System.out.println("i=" + i + ",j=" + j);
            if (j == 5) {
                break ok;
            }

        }
    }
}

十、方法(method)

1、何谓方法

System.out.println();
类 对象 方法
方法包含于类或对象中;
方法在程序中被创建,在其它地方被引用;
放在main方法外,保持代码整洁干净

2、方法的定义及调用(invoke)

  1. 类似于其他语言的函数,是一段用来完成特定功能的代码片段(复用代码)

一个细节:代码执行到return或者执行完最后一行代码,代表方法执行完毕
在这里插入图片描述

p
  1. 调用方法:对象名.方法名(实参列表)
    Java支持两种调用方法的方式,根据方法是否返回值来选择。
    1)当方法返回一个值时,方法调用通常被当做一个值。如:int largr = max(30,40)
    2)如果方法返回值是void,方法调用一定是一条语句。如:System.out.println(Hello,kuangshen)
    Java是值传递!

3、方法重载(overload)

概念:同一个类中,存在多个同名方法,但参数个数或参数类型不同。
特点:与返回值类型无关,只看参数列表,调用时根据参数列表的不同来区别。
示例:

int max(int a,int b);
int max(int a,int b,int c);
double max(double a,double b);

4、命令行传参:String[ ] args

参数String[ ] args的作用就是可以在main方法运行前将参数传入main方法中

1 public static void main(String[] args){
2     for(int i=0; i<args.length; i++)
3         System.out.println(args[i]);        //遍历输出args[]中元素    
4 }

5、可变参数…

JavaSE 5.0 中提供了Varargs(variable number of arguments)机制,允许直接定义能和多个实参相匹配的形参。从而,可以用一种更简单的方式,来传递个数可变的实参。

//JDK 5.0以前:采用数组形参来定义方法,传入多个同一类型变量
public static void test(int a ,String[] books);
//JDK5.0:采用可变个数形参来定义方法,传入多个同一类型变量
public static void test(int a ,String…books);

注:一个方法中只能指定一个可变参数,且必须是方法的最后一个参数,任何普通的参数必须在它之前声明。

package com.cskaoyan.kuangshenTest;

public class Demo1 {
    public static void main(String[] args) {
        //调用可变参数的方法
        printMax(34,3,3,2,65.6);
        printMax(new double[]{1,2,3,4});
    }
    public static void printMax(double... numbers){
        if(numbers.length == 0){
            System.out.println("No argument passed");
            return;
        }

        double result = numbers[0];

        //找出最大值
        for (int i = 1;i < numbers.length;i++){
            if(numbers[i] > result){
                result = numbers[i];
            }
        }
        System.out.println("The max value is " + result);
        
    }
}

6、递归(重点、难点、高频问点)

  1. A方法调用B方法,我们很容易理解!
    递归就是:A方法调用A方法!就是自己调用自己!
  2. 利用递归复杂问题简单化,把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,大大减少了程序的代码量。
  3. 递归结构包括两个部分:
    递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。
    递归体:什么时候需要调用自身方法。
package com.cskaoyan.kuangshenTest;

import java.util.Scanner;

public class digui {
    public static void main(String[] args) {
        //
        //System.out.println(f(3));
        digui a = new digui();
        int result = a.f(3);
        System.out.println(result);

    }
    public static int f(int n){
        if(n == 1){
            return 1;
        }else {
            return n*f(n-1);
        }
    }
}

十一、数组

1、数组概述

2、数组声明创建

  1. 声明数组变量,Java使用new操作符来创建数组int[] numbers = new int[10];
  2. 数组元素通过索引来访问,数组索引从0开始
  3. 获取数组长度:arrays.length
    下标合法区间:[0 , length - 1],如果越界就会报错;ArrayIndexOutOfBoundsException
  4. 初始化问题:创建一个数字数组时,所有元素初始化为0。boolean数组的元素会初始化为false。对象数组的元素则初始化为一个特殊值null,表示这些元素还未存放任何对象。
  5. 小结:
    1)数组是相同数据类型(可以为任意类型)的有序集合
    2)数组也是对象。数组元素相当于对象的成员变量
    3)数组长度是确定的,不可变的。不可以越界,否则异常。
public class Array1 {
    public static void main(String[] args) {
        //动态初始化,包含默认初始化
        int[] numbers = new int[10];//声明和创建一个数组
        numbers[0] = 130;
        numbers[1] = 140;
        System.out.println(numbers[0]);      //130
        System.out.println(numbers[2]);      //0

        //静态初始化
        int[] b = {1,2,3};
        System.out.println(b[2]);      //3
    }
}

在这里插入图片描述

3、数组使用(最重要)

普通的for循环
for-each循环(增强的for循环)

1、可以用来依次处理数组中的每个元素(其他类型的元素集合亦可)而不必为指定下标值而分心。
2、语句格式为:
for (variable : collection) statement collection这一集合表达式必须是一个数组或者是一个实现了Iterable接口的类对象(例如ArrayList)

for(int element : a){
	System.out.println(element);
}

3、在很多场合,还是需要使用传统的for循环。
4、一个更加简单的方式打印数组中的所有值,即利用Array类中的toString方法。
调用Array.toString(a),返回一个包含数组元素的字符串。

int[] a = {2,3,5,7,11,13};
System.out.println(Arrays.toString(a));

[2, 3, 5, 7, 11, 13]
数组初始化以及匿名数组

1、创建数组对象并同时赋予初始值的简化书写形式
甚至可以初始化一个匿名的数组

//不需要调用new
int[] smallPrimes = {2,3,5,7,11,13};
//右边:初始化一个匿名数组     重新初始化一个数组
smallPrimes = new int[]{17,19,23,29,31,37};
数组拷贝

将一个数组的所有值拷贝到一个新的数组中去,使用Arrays类的copyOf方法

        //数组拷贝
        int[] smallPrimes = {2,3,5,7,11,13};
        int[] luckNumbers = smallPrimes;
        luckNumbers[5] = 12;
        System.out.println(smallPrimes[5]);//now smallPrimes[5] is also 12

        //将一个数组的所有值拷贝到一个新的数组中去,使用Arrays类的copyOf方法
        //[2, 3, 5, 7, 11, 12]
        int[] copiedluckNumbers = Arrays.copyOf(luckNumbers,luckNumbers.length);
        System.out.println(Arrays.toString(copiedluckNumbers));

        //第二个参数是新数组的长度
        //[2, 3, 5, 7, 11, 12, 0, 0, 0, 0, 0, 0]
        int[] copiedluckNumbers_1 = Arrays.copyOf(luckNumbers,2 * luckNumbers.length);
        System.out.println(Arrays.toString(copiedluckNumbers_1));
数组排序

对数值型数组进行排序,使用Arrays类的sort方法
Java核心技术卷1P84java.util.Arrays 1.2
修饰符 返回类型 方法名(参数列表)

  • static String toString(type[] a) 5.0
    返回包含a中数据元素的字符串,这些数据元素被放在括号内,并用逗号分隔。
  • static void sort(type[] a)
  • 采用优化的快速排序算法对数组进行排序
  • 其他后续使用中再补充
数组逆序
查找数组中某元素位置
JVM内存模型

在这里插入图片描述
在这里插入图片描述
Java 虚拟机规范规定的区域分为以下 5 个部分:
程序计数器(Program Counter Register):当前线程所执行的字节码的行号指示器,字节码解析器的工作是通过改变这个计数器的值,来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能,都需要依赖这个计数器来完成;

Java 虚拟机栈(Java Virtual Machine Stacks):用于存储局部变量表、操作数栈、动态链接、方法出口等信息;
本地方法栈(Native Method Stack):与虚拟机栈的作用是一样的,只不过虚拟机栈是服务 Java 方法的,而本地方法栈是为虚拟机调用 Native 方法服务的;

Java 堆(Java Heap):Java 虚拟机中内存最大的一块,是被所有线程共享的,几乎所有的对象实例都在这里分配内存
方法区(Methed Area):用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。
堆和栈的区别:

物理地址
内存分别
存放的内容对象的实例和数组。关注数据的存储局部变量和操作数栈。关注的是程序方法的执行。
程序的可见度只对于线程是可见的,线程私有的。对于整个应用程序都是共享、可见的。

数组操作中两个常见问题

1、数组下标越界异常:ArrayIndexOutOfBoundsException
这个异常是专门针对数组操作的异常,原因是访问了不合法的下标

2、空指针异常:NullPointerException
空指针这种说法是沿袭C++而来的
null:空常量 如果对象的引用指向了null,就没有指向对象
比如数组,引用没有指向一个数组。但是这个时候,你想获取数组的长度,或者操作数组。那么就会产生空指针异常问题。

总结:
1、空指针异常不是数组独有的,而是只要是引用数据类型都可能产生这个错误
2、以后大家开发中,数据类型大多数都是引用数据类型,这就意味着你天天和空指针异常打游击,作斗争

  • 一旦产生空指针异常,程序就立刻终止,后面的代码也不执行
  • 避免空指针异常是我们使用引用数据类型必须要考虑的东西
  • 最简单的方法就是if判断null
命令行参数
数组作为方法入参
数组(数组名)作为返回值
public class Array2 {
    public static void main(String[] args) {
        //
        int[] arrays = {1,2,3,4,5};
        //知识点1、增强的for循环
//        for (int array : arrays){
//            System.out.println(array);
//        }
        //int[] reversed = new int[arrays.length];
        printArrays(turnreverse(arrays));
    }

    //反转数组
    public static int[] turnreverse(int[] arrays1){//知识点2、数组名作为方法的参数
        int[] result = new int[arrays1.length];

        //反转的操作
        for (int i = 0,j = result.length-1;i < arrays1.length;i++,j--){
            result[j] = arrays1[i];
        }
        return result;//知识点3、数组名作为返回值
    }

    //打印数组元素
    public static void printArrays(int[] arrays){
        for (int i = 0;i < arrays.length;i++){
            System.out.println(arrays[i] + "");
        }
    }
}

4、多维数组(升级)

  1. 可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其中每一个元素都是一个一维数组。
  2. 具体如下:
package com.cskaoyan.kuangshenTest;

public class weidu2_Array {
    public static void main(String[] args) {
        //
        int[][] array = {{1,2},{2,3},{3,4},{4,5}};

        System.out.println(array[0][1]);
        System.out.println(array[2][0]);

        printArrays(array[0]);//调用方法

        System.out.println();
        System.out.println("输出整个二维数组:");
        for (int i = 0;i < array.length;i++){
            for (int j = 0;j < array[i].length;j++){
                System.out.print(array[i][j] + "  ");
            }
        }

    }
    //打印数组元素
    public static void printArrays(int[] arrays){
        for (int i = 0;i < arrays.length;i++){
            System.out.print(arrays[i] + "  ");
        }
    }
}

5、Arrays类(操作数组)

# 定义
int[] a = {1,2,3,4,123,8,4567,234,412};
# 打印数组中元素
Arrays.toString(a)//[1, 2, 3, 4, 123, 8, 4567, 234, 412]

package com.cskaoyan.kuangshenTest;
import java.util.Arrays;

public class Array_API {
    public static void main(String[] args) {
        
        int[] a = {1,2,3,4,123,8,4567,234,412};
        System.out.println(a);       //[I@6e0be858

        //打印数组元素Arrays.toString
        System.out.println(Arrays.toString(a));//直接调用系统的方法//同下
        printArray(a);//自己设计的方法      //[1, 2, 3, 4, 123, 8, 4567, 234, 412]

        //数组进行排序
        Arrays.sort(a);
        System.out.println(Arrays.toString(a));    //[1, 2, 3, 4, 8, 123, 234, 412, 4567]

        //数组的填充
        Arrays.fill(a,2,4,0);
        System.out.println(Arrays.toString(a));      //[1, 2, 0, 0, 8, 123, 234, 412, 4567]
    }

    public static void printArray(int[] b) {
        //
        for (int i = 0;i <= b.length-1;i++){
            if(i == 0){
                System.out.print("[");
            }
            if(i == b.length-1){
                System.out.println(b[i]+"]");
            }else {
                System.out.print(b[i] + ", ");
            }
        }
    }
    
}

冒泡排序

package com.cskaoyan.kuangshenTest;
import java.util.Arrays;

public class maopao {
    public static void main(String[] args) {
        //冒泡排序
        //1.比较数组中相邻的2个元素,如果第一个数比第二个大,我们就交换它们的位置
        //2.每一次比较,都会产生一个最大或最小的数字
        //3.下一轮则可以少一次排序!
        //4.依次循环,直到结束!
        int[] a = {2,99,1,2,22,34,4,17,69,9};
        sort(a);
        System.out.println(Arrays.toString(a));
    }

    public static void sort(int[] array){

        boolean flag = false;//优化,如果不产生比较,就直接结束方法
        //外层循环,判断我们走多少次。如6个数,走5次:i = 0,1,2,3,4
        for (int i = 0;i < array.length-1;i++){
            //i = 0时,j = 0,1,2,3,4
            //i = 1时,j = 0,1,2,3,4
            for (int j = 0;j < array.length-1-i;j++){
                if(array[j+1] < array[j]){
                    int tmp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = tmp;

                    flag = true;
                }
            }
            if(flag == false){
                break;
            }
        }
    }

}

6、稀疏数组

package com.cskaoyan.kuangshenTest;

public class xishujuzhen {
    public static void main(String[] args) {
        //1.创建一个二维数组11 * 11     0:没有棋子   1:黑棋      2:白棋
        int[][] array1 = new int[11][11];
        array1[1][2] = 1;
        array1[2][3] = 2;
        //输出原始数组
        System.out.println("原始的数组:");

        for (int[] a : array1){
            for(int b : a){
                System.out.print(b + "  ");
            }
            System.out.println();
        }

        System.out.println("======================");

        //转换为稀疏矩阵保存
        //获取有效值的个数
        int sum = 0;
        for (int i = 1;i < 11;i++){
            for (int j = 1;j < 11;j++){
                if (array1[i][j] != 0){
                    sum++;
                }
            }
        }
        System.out.println("有效值的个数为:" + sum);

        //2、创建稀疏数组
        int[][] array2 = new int[sum + 1][3];

        array2[0][0] = 11;
        array2[0][1] = 11;
        array2[0][2] = sum;

        int count = 0;
        for (int i = 0;i < array1.length;i++){
            for (int j = 0;j < array1[i].length;j++){
                if (array1[i][j] != 0){
                    count++;
                    array2[count][0] = i;
                    array2[count][1] = j;
                    array2[count][2] = array1[i][j];
                }
            }
        }
        System.out.println("稀疏数组为:");
//        for (int i = 0;i < array2.length;i++){
//            for (int j = 0;j < array2[i].length;j++){
//                System.out.print(array2[i][j]+"\t");
//            }
//            System.out.println();
//        }
        for (int i = 0;i < array2.length;i++){
            System.out.println(array2[i][0]+
                    "\t"+array2[i][1]+
                    "\t"+array2[i][2]);
        }

    }
}

原始的数组:
0 0 0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0
0 0 0 2 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0

有效值的个数为:2
稀疏数组为:
11 11 2
1 2 1
2 3 2

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lacrimosa&L

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值