Java-- 2语言基础关键字、标示符、常量、变量和运算符、语句、函数、数组、常见算法...

 1.    Java中的关键字
1). 关键字的基本含义
(1). 关键字就是被程序语言赋予特殊含义的词
(2). 关键字的特点就是:所有的关键字都是小写
2). Java中关键字的分类 (根据用途分类)
 
(1). 用于定义数据类型的关键字
byte、short、int、long、float、double、char、boolean
class、interface
void
(2). 用于定义数据类型值的关键字
true 、false
null
(3). 用于控制流程语句的关键字
if 、else、switch、case、default、while、do、for、break、continue、return
(4). 用于定义访问权限修饰符的关键字
private、protected、public
(5). 用于定义类、函数、变量修饰符的关键字
abstract、final、static、synchronized
(6). 用于定义类与类、类与接口之间关系的关键字
extends、implements
(7). 用于建立实例及引用实例、判断实例的关键字
new、this、super、instanceof
(8). 用于异常处理的关键字
try、catch、finally、throw、throws
(9). 用于包的关键字
import、package
(10). 其他关键字
native、transient、volatile、assert
 
*****注意:main不是关键字,但是确是能被JVM识别的一个名称(非常特殊)
2.   Java中的标示符
1). 标示符是程序中自定义的一些名称
2). Java中标示符的组成规则
(1). 26个英文字母的大小写
(2). 数字0-9
(3). 特殊符号_和$
Java中仅有下划线“_”和美元符“$”两个符号用于可以用于构成标示符的一部分
3). 合法标示符的组成原则
(1). 数字不能开头
(2). 不能使用java关键字作为标示符
******所以  两个特殊符号 $和_可以用作为标示符的开头 $D和_ABC都是合法的标示符
4). Java中严格区分大小写
3.    常量
1). 不能改变的数值成为常量
2). Java中常量的分类
(1). 整数常量
       Java中的整数常量有三种表现形式:
       【1】十进制(0-9 表示)
【2】八进制(0-7 表示),用0开头
注意080一定是非法的常量表示
【3】十六进制(0-9,A-F 表示),用0x开头
一个数有多中表现形式,但都是表示同一个数
 
(2). 浮点数常量
(3). 布尔型常量
       仅有两个取值:true和false
(4). 字符型常量
(5). 字符串常量
(6). null常量
       仅有一个取值:null
3). 负数的二进制****
问:请计算-6(D)的二进制
错误答:按位取反加一   110--à001再加1 -à 101(X)
由于正数的最高位都是0,所以在进行二进制转换的时候,可以不用考虑存储的高位
但是 负数不行!!!
6这个整数在内存中占了4个字节,所以应该是0000-0000 0000-0000 0000-0000 0000-0110
按位取反的时候一定要考虑高位为0的部分!!
1111-1111 1111-1111 1111-1111 1111-1001

不考虑高位为负数按位取反的结果是完全不一样的
0000-0000 0000-0000 0000-0000 0000-0001
 
再加1
1111-1111 1111-1111 1111-1111 1111-1010
 
规律:负数二进制的最高位为1
         正数二进制的最高位为0
4.   变量
1). 将不确定的数据进行存储
       也就是需要在内存中开辟一段空间
2). 如何开辟内存空间
       就是明确数据类型、变量名和初始化数据便能在内存中开辟空间。
** 开辟内存空间的三要素
3). 数据类型的分类
(1). 基本数据类型
       基本数据类型有3种
[1]. 数值型 (2种):
【1】整型(4种): byte(1B)、int(4B)、short(2B)、long(4B)
int 类型为整型数据的默认数据类型
【2】浮点型(2种):float、double(8B)
double类型为浮点型数据的默认数据类型
[2]. 布尔型(1种)boolean
[3]. 字符型(1种)char (2B)
 
(2). 引用数据类型
       引用数据类型有3种
       [1].类类型:class
[2]. 接口类型:interface
[3]. 数组类型:[]  记住:数组是单独的引用数据类型
1.    标示符(重点部分)
1). 算数运算符
(1). 除法运算符 /
(2). 取模运算符 % (也是取余运算)
负数取模运算:结果的符号看被模数 (验证过程就使用大除法即可)
e.g. -1%5 = -1
   17%-5=2

个人总结:这个结论不用记,只要是直接用大除法运算一下就OK
(3). 转义字符
通过“\”来改变后面字母的含义。转义之后,\和后面的字母变成一个整体
[1]. \n换行 \b退格  \r按下回车  \t制表位
[2].        Linux中, \n表示回车(由一个转义字符表示)
Windows中, \r\n表示回车(由两个转义字符表示)
DOS中, 直接识别\n (由一个转义字符表示)
2). 比较运算符
比较运算符的结果只能是boolean类型的,要么为true 要么为false
instanceof 也是比较运算符!!!!!!! 所以instanceof运算结果一定是true或者false中的一个
3). 逻辑运算符
(1). !、||和&&
       !逻辑非  ||和&&是短路或和短路与
(2). &和|
       &和|是非短路运算
(3). 短路运算和非短路运算的区别
       [1].短路运算:
||:左边结果是true,右边表达式不用运算
&&:左边结果是false,右边表达式不用运算
       [2].&和|无论左边的结果是什么样,右边的表达式都要进行运算。
(4). &和|的第二个作用就是做位运算符
4). 位运算符
(1). ~按位取反运算
       注意:按位取反的时候,要考虑这个变量在内存中所占的位数来进行运算。否则运算结果是错误的!!!!
e.g. ~6的结果是多少?
       Step1.由于是按位取反运算,所以要考虑这个数的内存情况。6默认是int类型的常量,所以占4B,所以内存中应该是0000-0000 0000-00000000-0000 0000-0110
按位取反的结果就是  1111-1111 1111-1111 1111-11111111-1001
 
e.g.2 接着问:1111-1111 1111-11111111-1111 1111-1001 对应的十进制数字是多少?
不用真的去运算,间接做!
上面的二进制数是~6。而6按位取反加一的结果就是-6在内存中的存储结果
所以 ~6+1(D) =-6(D) =è ~6 =-7(D)
所以  以上的二进制数对应的十进制数字就是-7
(4). ^异或运算
异或运算的特点:一个数字异或同一个数字两次,结果还是这个数字
应用:异或运算的这个特点可以对数据进行简单的加密和解密
(5). 移位运算
[1]. 如何获取一个32位二进制数字的最低四位?
       让这个数和0x0000000f做&运算;
[2]. 如何获取一个32位二进制数字的次低四位?
       先让这个数字向右移位四位再和0x0000000f做&运算;
       假设这个数为A 次第四位为:int x=(x>>4)&0x0000000f;
[3]. >>和>>>的区别?
       整数移位时候,两者结果一样,没有区别;
       负数移位时候,>>仍用1来填充移位之后的高位数;>>>采用0作为高位填充数字
5). 三目运算符
格式 条件表达式?表达式1:表达式2
注意!!!三目运算符的结果的类型是表达式1和表达式2的计算结果类型的提升!!!!!
e.g. y =(x >1)? ‘a’ :200
   如果:x>1成立,打印的结果是97 而不是’a’, 为什么?
              因为三目运算符的结果数据类型是两个表达式结果数据类型的共同提升。’a’为char 200默认是int 共同提升为int  所以  ‘a’被提升为97输出!                                        

流程控制语句(重点概述)
1). 条件语句
(1). If、if-else和if-else if- elseif-…else 注意事项
[1].if-else和三目运算符的关系
       {1}.三目运算符是if-else的简写
       e.g.int a= 9, b;
          b =(a> 1)? 100:200;
          等价于
          if(a >1) b =100; else b =100;
        三目运算符书写方便,所以两者等价的时候,推荐使用三目运算符
       {2}. 只要是简写,那就存在着局限性。
       {2}.1三目运算符只能简写if和else中处理内容为一条语句的情况。
       {2}.2三目运算符条件表达式以外的每一个表达式对应的执行语句必须有返回结果。
               只要是表达式,就必须要求有一个完整的返回结果
        e.g. if (a>1)
System.out.println(“Hello World!”);
              else
                     System.out.println(“abc”);
       如果简化成
       (a >1)? System.out.println(“Hello World!”):System.out.println(“abc”);
由于PrintWriter的println方法返回值为void  所以不满足三目运算符除条件表达式以外都要有返回结果的条件,导致编译出错。
(2). switch---case语句
[1]. 涉及四个关键字:switch、case、break和default;
[2]. switch-case语句执行顺序:前提没有break语句存在。无论多个case和default之间的相对位置关系如何,都是先执行符合条件的case语句,最后执行default (无论default在哪,哪怕是在最前面,也是最后执行)。
[3]. switch-case语句的2种结束形式:
       {1}.如果有break存在,执行到break语句。匹配上对应的case之后,执行到匹配的case之后,直到遇见break就停止。;
       {2}.如果没有break存在,执行到switch的右边“}”
e.g.
int x =6;
        switch(x){
            default: System.out.println("d");break;
            case 4: System.out.println("a");break;
            case 6: System.out.println("b");break;
    }
执行过程就是x从写在最前面的case开始匹配。6!=4跳过,但是6=6执行里面的输出语句,发现里面有break语句,执行完syso(”b”)就结束了。
int x =6;
        switch(x){
            default: System.out.println("d");
            case 6: System.out.println("b");
case 4: System.out.println("a");
        }
这个时候,执行顺序就是先和6=6,成立,执行syso(”b”); 由于此时没有break,有没有右大括号},所以程序要继续执行下去。而不再判定case中的对应的条件是否满足。直到执行完default中的内容,遇见}程序才停止。
[4]. switch中被选择的表达式只能接受4中类型的变量,byte, short, int和char 不接受long!!!
       Java5之后,接受枚举类型的变量
Java7之后,接受String类型的变量
(3). 循环语句
【1】. for循环的格式:
for(初始化exp;循环条件exp;循环体执行后操作的exp){
       循环体
}
注意:{1}.中间的exp返回值一定要是boolean类型的值!!否则编译出错!!!
e.g          for (System.out.println("a");
                System.out.println("b"); System.out.println("c")) {
            System.out.println("d");
           
        }
由于中间的输出表达式执行完之后,返回void所以编译会出错!!!
    {2}. 最后一个表达式一定是在for中的循环体执行完之后,才执行!!!!
       {3}.第一个表达式仅仅是初始化作用,仅仅执行一次。
       {4}.第一个和第三个表达式没有特殊的要求,是合法的表达式即可。
【2】.无限循环的两种表示形式:
       {1}.采用for循环构成无限循环语句
              关键在于:中间条件表达式不写,为空,for循环默认是true
              for(;;){} <=è for(;true;){}
    {2}. 采用while循环构成无限循环语句
        while(true){}
(4). break和continue语句
[1]. break和continue语句都与自己的作用范围,离开这个范围,这两个关键字不起作用!!!!
       如果在应用范围之外写了continue或者break语句,会编译出错。
       {1}.break作用范围有2个:选择结构switch和循环结构
              break表示跳出对应的case或对应的循环体。
              break可以加标号实现跳出指定的循环。
             
e.g.    w:for (int i = 0; i < 3; i++) {
            q:for (int j = 0; j < 3; j++) {
                System.out.println("x");
                break w;//跳出最外层循环。
            }
        }
    {2}. continue作用范围只有1个:循环结构
程序执行到continue语句时候,其后的语句便不在被执行,而是跳到下一次循环。但是for循环的exp3是在continue执行完要立刻执行的。
结论:continue直接使得程序跳转到for的exp3,然后再执行下一次循环!!
       {3}.return、throw、continue和break单独存在时,前面可以加语句,但是他们的后面不能加任何语句!!!因为执行不到,所以只要在return、throw、continue或者break之后加了语句,就会编译报错。e.g.
for (System.out.println("a");;System.out.println("c")) {
            break;
            int x =2;//编译出错!!!!!! 
    }
2.   函数
1). 函数:就是在类中具有特定功能的一段程序
2). 函数的基本语法格式:
       修饰符    返回值类型    函数名(参数列表){
              执行语句
              returnxxx;
}
注意:函数不能嵌套定义!!!
public static void A(){
            public static void B(){// 嵌套定义  编译出错!!!
           
            }
    }
3). 如何定义一个函数?
 (1). 首先明确函数的计算结果是什么;
(2). 明确在定义功能的过程中是否需要未知的内容参与运算
4). 函数的重载
(1). 概念
       在同一个类中(这是范围),允许存在一个以上的同名函数,只要他们的参数列表不一样即可(要么参数个数不一样,要么参数类型不一样)
(2). 重载的特点
       重载要求函数名相同但是参数列表不同,其余的返回值类型、修饰符和是否抛出异常与两个函数在一个类中是否构成重载没有关系。
(3). 何时使用重载
       当定义函数的功能相同,但是参与运算的位置内容(也就是函数的参数)不同,这时候,可以根据函数具有相同的功能定义函数名称相同的函数,但是参数列表不同。函数名相同便于进行阅读。      

1.    数组的相关基本概念
1). 数组的概念
(1).定义
       同一种类型数据的集合。数组是一种容器。
(2). 容器的概念
能存储数据的地方就是容器
(3). 数组的优势
能够自动为数组中的元素自动从0开始进行编号,方便对元素的操作。
(4). 关键字new的作用
       [1]. 用来在内存中产生实体
       [2].实体:包括类的对象和数组(数组和类对象可以通称为new建立的实体)
(5). 数组的数据类型
数组是Java中一种独立的数据类型
Java中三种引用类数据类型:class、interface和[]数组类型。
2). Java的内存结构
(1). Java的五大内存区域
[1].栈内存、堆内存、方法区、本地方法区和寄存器
       个人觉得分成了方法区和本地方法区是因为:方法区本身是Java语言编写的方法,而本地方法区是Java调用底层操作系统的方法。两者有本质的区别,所以分成了两片内存区域
[2]. 栈内存的特点
       {1}.存放的内容:用于存储定义在方法中和局部代码块中局部变量
       {2}.栈内存的管理:所占用的空间直到相对应的代码块或者方法执行完就立即自动释放
[3]. 堆内存的特点****(助记:存储内容、内存地址值、默认初始化值和垃圾回收机制(GC机制))
       {1}.存储的内容:通过new建立的实体全部存放到堆内存中
       {2}.每一个实体都有自己的内存地址值
       {3}.实体中的变量都有默认的初始化值
       {4}. 当实体不再被使用的时候,会在不确定的时候,有垃圾回收器 (GC)回收(释放空间)
(2). 数组的初始化过程****
       举例说明:int[] arr =newint[3]; //体现堆内存4个特点
【step 1】在栈中为数组类型的变量arr开辟空间。
【step 2】赋值运算右边是new运算。new得到的数组实体在堆内存中开辟空间
【step 3】系统为堆内存中的数组对象分配地址(地址值)。假设为0x0079
【step 4】系统自动为数组中的元素进行初始化(默认值)。这里是int, 值全部为0
【step 5】此时将数组实体的首地址赋值给左边栈内存中的arr变量。arr值为0x0079
【step 6】赋值完成后,x就指向了这个数组实体也叫x引用了这个数组实体。

(3). Java中的垃圾以及垃圾回收机制 (GC机制)
[1]. Java中的对象何时变成垃圾?
当一个堆内存中的对象在栈中没有引用指向它的时候,这个对象就被JVM视为垃圾
[2]. 垃圾不会被立刻清理掉,而是在未知的时间点,JVM启动GC来回收这个对象所占用的空间。
[3]. Java中的垃圾回收机制(和C++相比)
Java中不用手动清除堆内存对象,只要将堆内存中的对象变成垃圾,这个垃圾对象就会被GC在某个不确定的时间自动清除掉。
(4). 堆内存对象Prac
int[] x =newint[3];
int[] y =x;
y[1] =89;
x =null;


请问这段程序执行完之后,在堆内存中有没有垃圾对象?
分析:由于x变成null之前,已经把数组的首地址的值传给了y,所以x变成null之后,y还是指向了内存中的数组对象,所以程序执行完之后,对内存中的数组对象在栈内存中仍然有引用变量指向它,所以堆内存中没有垃圾对象。
如图:

 
3). 数组初始化以及常见的问题
(1). 数组初始化的方式及其注意事项
       [1].通过显式new进行初始化
       {1}.不明确数据:int[] arr =new int[整数]; <===> int arr[] =new int[整数];
       {2}.明确数据:int[] arr =new int[]{1,2,3,4,5,6}; 
一定注意!!明确数据之后,new中的[]千万别写整数!!!
       [2].显式new的简化形式:
              明确数据:int[] arr ={1,2,3,4,5,6}; //仅仅就是{}来初始化就可以了!!!
(2). 数组越界为什么编译器不进行检查呢?
****原因:因为new之后在堆内存中开辟空间,并划分出多少小的数组元素单元这个动作是在程序运行的时候才进行的,不属于编译的范围之内!!!!
编译要进行的就仅仅是:语法检查!!
举例说明:
int[] x =new int[3];
//javac要做的:合乎数组定义的语法么?检查两边赋值的类型一样么?一样 OK
至于new要在内存中开辟空间,不是javac的职责范围之内,所以javac并不关心这个里面的数字到底是多少!编译只是关心使用的时候,符合语法的模子就行。不符合,就出错!!
System.out.println(x[3]);
由于javac不知道数组在内存中会被开辟几个空间,所以访问x中的第几个元素并不关心。只要是满足引用数组元素的语法:数组名[下标值] 这个模子即可。
***************************
但是 运行时候,new会在堆内存中开辟空间,可访问的数组元素名是:x[0], x[1]和x[2]。但是在运行打印x[3]的时候,JVM找不到这个元素 抛出数组越界异常。    
(3). 通过程序打印数组的类型

1.    获取数组中的极值
1). 获取数组中的最大值 (最小值的思路相反)
(1). 思路1:
临时变量作为值最大的元素,初始化存放数组的第一个元素。
(2). 思路2:(存放元素的角标是比较正统的做法)
临时变量作为值最大的元素对应的角标(也就是索引0),初始化为0。
/**
* 获取传入的数组的最大的索引值
* @param arr:要获取最大值的数组
* @return
*/
private static int getMaxIndex(int[] arr) {
//定义数组最大值的索引为数组的第一个元素角标0
int maxIndex =0;
//遍历数组中的每一个元素
for(int i=0; i<arr.length; i++){
//如果遍历到的数组元素的值比现有的最大值还大,就更新数组最大值的索引位置
if(arr[i] >arr[maxIndex])
//把数值最大的索引值更新
maxIndex=i;
}
//返回找到的数组最大值对应的索引值
return maxIndex;
}
//测试程序
public static void main(String[] args) {
//定义要获取最大值的数组
int[] arr ={42, 111, 112, 35, 635};

//通过getMaxIndex方法获取数组中最大元素的索引值
int maxIndex =getMaxIndex(arr);

//打印获取到的数组最大的值的索引和对应的值
System.out.println("数组中最大的元素的位置: arr["+maxIndex+"] ="+ arr[maxIndex] );
}


2). 获取数组中的最大值
思路和获取数组的最小值类似。
2.    数组中的排序算法
以从小到大排序作为案例
1). 选择排序 select sort
(1). 选择排序的基本思想:
[1]. 每次都拿数组中特定位置上的值和该位置以后的所有元素依次比较,如果这个元素比后面的元素的值大,那就换位。否则不换位。
[2]. 即使在一次循环中即使有换位发生,也仍然那这个值变化但是位置还是不变化的元素继续和数组中的该元素以后位置的元素进行比较。
[3]. 图例进行说明:

【*】选择排序形象记忆图:


****特点:
{1}. 完成第n次循环之后,索引位置为0、1、2、…、n-1的元素是依次是这个数组的第1 min(最小的)、第2 min、第3 min、….、第n min的元素。
{2}. ***第x次循环能确定出第x-1位置上为数组的第x min的元素。****(一定记住!!)
{3}. 完成一次循环,低位索引的元素固定下来
(2). 选择排序的示例代码
技巧:循环到最后一个角标的时候,只剩下一个元素,所以不用比较。
/**
* 1. 选择排序
*/
public static void selectSort(int[] arr){
for(int i=0; i<arr.length-1; i++){ //最后一个元素不用比较
for(int j=i+1; j<arr.length; j++){
if(arr[i] >arr[j]){
swap(arr,i, j);
}
}
}
}

/**
* 数组元素互换位置
*/
private static void swap(int[] arr, int x, int y){
int temp =arr[x];
arr[x]=arr[y];
arr[y]=temp;
}    
2). 冒泡排序 bubble sort
(1). 冒泡排序的基本思想:
[1]. 每次都是从第0位开始,相邻元素依次比较,如果低位的元素值大于相邻高位索引的元素的值,就换位。否则高位索引的元素和他下一个元素作比较。依次进行。
[2]. 图例说明

****特点:
{2}. ***第x次循环能确定出倒数第x-1位置上为数组的第x max的元素。****(一定记住!!)
{3}. 完成一次循环,高位索引的元素固定下来
【*】冒泡排序形象记忆图:

(2). 冒泡排序的实例代码
技巧:内层循环主要是a[j+1]和a[j]相邻元素之间的比较
这两个角标都要满足数组长度不越界
j+1 <=arr.length-1-i
j <=arr.length -1-i
不等式的交集 j<= arr.length –i-1
/**
* 2. 冒泡排序
*/
public static void bubbleSort(int[] arr){
for(int i=0; i<arr.length; i++){
for(int j=0; j< arr.length-i-1; j++){
swap(arr,j+1, j);
}
}
}


(3). 选择排序和冒泡排序的对比(一次循环之后)
 
固定下来的元素
最值问题
固定的始、终
循环过程特点
冒泡排序
高位索引
本次循环的最高索引为某个最大值
每次都从第一个元素比较
始固定
起始点不动,
终止点后移
选择排序
低位索引
本次循环的最低索引为某个最小值
每次都比较到最后一个元素
终固定
起始点前移
终止点不动
 


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值