首页 > 代码库 > Java基础知识二次学习-- 第二章 基础语法与递归补充

Java基础知识二次学习-- 第二章 基础语法与递归补充

第二章 基础语法与递归补充
 
时间:2017年4月24日10:39:18
章节:02章_01节,02章_02节
视频长度:49:21 + 15:45
内容:标识符,关键字与数据类型
心得:由字母,下划线,$,数字组成,应该由字母,下划线$开头,同时应该避开java保留字符
 
技术分享

 

变量是内存中的一小块区域,使用变量名来访问这块区域
技术分享

 

 
执行过程中的内存管理(疑问:这里的内存和Jvm的一样吗?)
code segment 存放代码
data segment 静态变量 字符串常量
stack 栈 局部变量
heap 堆 new出来东西
顺序
1.Load到内存区
2.找到main方法开始执行
 
java变量里包括成员变量和局部变量
 
局部变量:方法或语句块内部定义的变量
成员变量:方法外部,类的内部定义的变量
之前一直理解成全局变量(事实上Java是面向对象的语言,变量都要和对象挂钩,因此只有属于对象的成员变量与下面的局部变量
所以不存在全局变量)
 
Java数据类型的划分 分为基本数据类型与引用数据类型
基本数据类型
数值型 字符型(char) 布尔类型(boolean)
数值型里面又分为
整数类型(byte,short,int,long)
浮点类型(float,double)
 
引用数据类型
类(class) 接口(interface) 数组
 
boolean类型
Java里的boolean类型只允许取得true或者false,不可以取0或者非0(这点与C语言不同)
 
char类型
java字符采用Unicode编码,每个字符占两个字符,所以可以用16进制的编码形式表示,默认采取UTF-16
java中允许使用‘\‘作为转义字符
 
<java核心技术 卷1> 补充:
\u0000到\uffff Unicode编码单位可以表示为16进制数值
包括了特殊转义字符
在java中,char类型用Utf-16编码描述一个代码单元
从JDK5.0开始 代码点是指一个编码表中的某个字符对应的代码数值
第一个级别代码为基本的多语言级别,从U+0000到U+FFFF 包括了经典的
Unicode代码 其余的16个级别代码点分别从U+10000 到U+10FFFF ,包括了一些辅助字符
 
整数类型(byte,short,int,long)
 
类型 占用存储空间 表数范围
byte 1个字节 -2的7次方到2的7次方-1
short 2个字节 同上,和位数相关
int 4个字节 同上,和位数相关
long 8个字节 同上,和位数相关
 在java里没有无符号的整数,所有的数都是带符号的,因此位数里要单独拿出一位来做符号
因此,例如byte,1个字节,8位就是-2的7次方到+2的7次方-1(因为有个0,所以要-1)
java各整数类型又固定的表数范围和字段长度,不受具体操作系统的影响,以保证java程序的可移植性
 
Java语言的整形常量默认为int型
声明long型常量可以加上"l"或"L" 一般都L 因为小写l看起来像1
 
浮点类型(float,double)
java中浮点类型一般两种表示形式
1.十进制,如3.14 314.0 .314
2.科学计数法 如 3.14e2 3.14E2
默认为double类型 如果说要声明一个float类型,后面要加f
例如float =12.3 这个就是错误的 因为double 转float属于大转小 不能进行强制转换需要声明是f float=12.3f
例如
float 4个字节 double 8个字节
float精度是7位,double精度是15位
 
时间:2017年4月24日13:33:06
章节: 02章_03节 02章_04节
视频长度:20:00 + 2:00
内容:标识符关键字与数据类型
心得:
boolean:与c++不同,java里boolean类型可以和其他类型的互相转换
char:字符型进行运算的时候,使用ASC编码运算
容量小的类型自动转换为容量大的数据类型(而不是字节长度)
从小到大排序为:byte,short,char-->int-->long-->float-->double
其中byte,short,char三者不会互相转换,他们会首先转换成Int类型
Int 转成byte,short,char时,如果没有超过他们的范围是可以直接转的
如果超过了就要强制转换并且会进行截断
<java 核心技术 卷1> 补充:
技术分享

 

如图所示,实心箭头表示无损失的转换,虚箭头表示可能会有损失的转换
如int的123456789转换为float型,包含的位数比float类型能表达的位数多,所以转换之后大小是一样的,但是却损失了一定的精度
 
大转小的话,要加入强制转换符,但可能会造成精度的降低或者溢出,使用的时候需要格外注意
 
多种数据类型进行混合运算的时候,系统首先自动的将所有数据转换成容量最大的那一种数据类型,然后进行计算
 
实数常量默认为double 整数常量默认为int
 
例子 Int转byte的时候 4个字节转成1个字节,将前面的3个字节直接截断掉,剩下的字节是几就是几
 
double转float 浮点数在计算机内部用特殊的形式表示,中间专门存了一个小数点来计算小数点后有几位 所以不能不能直接截断
超过范围了 显示infinity
 
小数类型转换为整数,例如float转换成long,会强制舍弃小数部分(不是四舍五入)
 
时间:2017年4月24日14:31:15
章节:02章_05节
视频长度:13:27
内容:程序格式
心得:大致就是一些程序格式的规范
1.大括号对齐 2.遇到大括号缩进 3.方法与方法,程序块之间加一个空行
4.并排语句之间加空格 5.运算符两侧加空格 int i = 8;(特殊情况除外)
6.{前面有空格 7.成对编程
宗旨就是:让别人看的更清楚,让别人看的更舒服
 
时间:2017年4月24日14:42:54
章节:02章_06节
视频长度:20:42
内容:运算符
心得:
技术分享

 

 
 
自增运算符
i++,先取值再运算
++i,先运算再取值(一般不建议这么写--<java 核心基础 卷1>)
 
逻辑运算符
& 与 
|   或
! 非
^ 异或 相异为true ,不同的为true
&& 与|| 如果前面条件成立了,后面的就不运算了
 
赋值运算符
“=”两侧数据类型不一致时,可以适用默认的类型转换或者适用强制类型转换原则进行处理
注意:可以直接将整形常量直接赋值给byte,short,char等类型,而不需要进行强制类型转换,只要不超出其表数范围
+=,-=,*=,/=,%=
 
字符串连接符
int id = 800 + 90;
String s = "hello" + "world";
注意:"+"运算符两侧的操作数只要有一个是字符串(String)类型,系统会自动将另一个操作数转换为字符串然后再进行连接
当System.out.println 打印语句的时候
无论任何类型,都自动转换为字符串进行打印
int c = 12;
System.out.println(c);
内部会首先将12转换为字符串然后再打印出来
 
表达式
表达式是符合一定语法规则的运算符和操作数的序列
表达式值的类型就是表达式的类型
 
关于表达式的运算顺序 
由高向低进行运算(了解为主),一般不太确定的运算加
()就可以
技术分享

 

 
 
 
三目运算符
x ? y : z
回想起来了有一道问el表达式的三目运算的题目
${(requestScope.userId > 5) ? "大于5" : "小于5"}
 
多级三目运算符,从里往外算
 
时间:2017年4月24日15:07:53
章节:02章_07节   02章_08节 02章_09节
视频长度:20:01 5:00 1:00
内容:if分支与for循环 作业部分 作业部分补充
心得:
 
if语句
if else,else if,......
只有一句需要执行的语句,可以省略{}(但个人觉得最好不要省略,容易结构不清)
 
循环语句
for循环(i=0;i>5;i++){}
第一个是初始化,第二个是判断条件,第三个是执行语句结束之后作的判断
注意,这里的i的作用范围是在for循环里面
jdk 1.5之后的forEach循环,用于遍历集合或者数组
例如:
for(Student s : StudentList<Student>)
{
    System.out.println(s.getStudentName())
}
 
技术分享

 

 
public static void main(String[] args) {
    int result=0;
    for (int i = 0; i < 100; i += 2) {
        result += i;
    }
    System.out.println("结果是"+result);
}
 
时间:2017年4月24日15:37:05
章节:02章_10节
视频长度:11:42 5:55
内容:whlie & do while 语句 break& Continue语句 以及一些例子
心得:
while 先判断再执行 do-while 先执行再判断
break 语句用于终止某个语句块的执行,可以强行跳出循环, 用于终止本轮循环
错误实例之:
if(i == stop);break;
;从某种意义上来说其实可以理解成为一个空语句
事实上是这样的
if(i == stop){
;
}
break;
因此在用到break或者continue循环的时候一定不要在if()后加分号,不然代码多了不太容易能排出这种错误
 
continue 语句用于终止本次循环
 
记得之前看到过一个问题 如何一次性跳出多重循环?只是隐约记得可以用break 跳到一个标记处
例如  就可以跳到ok处
 
ok:
while(){
  for(){
    for(){
 
     break ok;
}
 
}
 
}
 
for(int i = 1; i <= 5; i++){
     //当i等于skip时, 跳过当次循环
     if(i == skip ) continue;
     System.out.println("i =" + i);
}
 
两个例子
1.输出1~100内前5个可以被3整除的数。
思路就是遍历1-100 每次加1, 找到一个数num就+1,num==5的时候就break跳出
 
public static void main(String[] args) {
    int num = 0;//用于计算找到的数
    System.out.println("1~100内能被3整除的前5个数是");
    for (int i = 1; i < 100; i++) {
        if (i % 3 == 0) {
            System.out.print(i+" ");
            num++;
        }
        if (num == 5){
            break;
        }
    }
}

 
2.输出101~200内的质数
思想是 首先什么是质数 质数是只能被1和自己整除的数字 
所以 所有的偶数都不是质数 这样可以减少一半次数的遍历
首先是对101~200内所有的奇数进行循环
对于每一个这样的奇数,将每一个小于他的数对他取余,如果余数为0,则代表可以整除,意味着这个数不是质数,跳出因子数寻找的循环,并将这个数标记为非质数(定义一个boolean)
如果所有的余数都不为0,那么意味着整个数是质数,则打印出来
 
 
/**
* 2.输出101~200内的质数
*/
public static void problem2() {
    boolean flag = true;
    for (int i = 101; i <= 200; i += 2) {
        flag = true;
//下面的是因子寻找循环,进入到if条件里的说明找到了因子,也                 意味着这不是一个质数
        for (int j = 2; j < i; j++) {
            if (i % j == 0) {
                flag = false;
                break;
            }
        }
        if (flag) {
            System.out.println("找到一个质数,这个质数是" + i);
        }
    }
}

 
本来是这么写的,只有红色的,后来发现只要找到一个质数之后boolean没有重置,后来就加了个蓝色的重置,
 
后来又发现既然这个boolean类型的数值只在循环里用,我为什么不直接定义在循环里呢,反正是局部变量,用完自动回收。
 
 
/**
* 2.输出101~200内的质数
*/
public static void problem2() {
    for (int i = 101; i <= 200; i += 2) {
        boolean flag = true;
        //下面的是因子寻找循环,进入到if条件里的说明找到了因子,也意味着这不是一个质数
        for (int j = 2; j < i; j++) {
            if (i % j == 0) {
                flag = false;
                break;
            }
        }
 
        if (flag) {
            System.out.println("找到一个质数,这个质数是" + i);
        }
    }
}

 
时间:2017年4月24日16:35:47
章节:02章_12
视频长度:09:03 
内容:switch语句的相关使用
心得:
switch(i){
case 1 :
     System.out.println("1");
     break;
case.....
......
}
switch(表达式) 表达式里只能是int 或者是等价Int的数据类型(byte,short,char,Int)(jdk 1.6(包括1.6)之前)
注意:(由于视频讲解版本是1.5,事实上java1.7开始支持了switch表达式里存放String字符串)
例如: 输出"我的名字叫小红"
String name = "小红";
switch (name){
    case "小红" :
        System.out.println("我的名字叫" + name);
        break;
}
 
以及,使用switch case的时,注意要加break;,否则的会一直执行下去,直到碰到下一个break;才跳出,这种错误编译器并不会报错
 
以及多个case语句可以合并
例如上面的
case "小红" :
case "小绿" :
     System.out.println(123);
     break;
 
default 可以省略,但不推荐省略,这样程序比较健壮
default:
     xxxx;
     break;
 
时间:2017年4月24日16:52:11
章节:02章_13
视频长度:20:08
内容:java方法
心得:
这其实是java封装的一种,我要什么,程序就给我什么,不需要让使用者去关心怎么做到的
例如:你给我钱,我给你饭,不需要让客户去关心饭是怎么做出来的
(钱就是参数,饭就是返回值,这个方法是饭店里的一种叫做买饭的方法)
在代码层面 可以减少重复代码的使用 ,忘记谁说的了,写代码最好不要有任何一行重复的代码,虽然实际情况很难做到,但要尽量往这个方面去靠
Java中进行函数调用中传参数时,遵循值传递的原则:
基本类型传递的是改数据值本身。引用类型传递的是对 对象的引用 ,而不是对象本身
关于这个值传递的看过一个不错的相关问题与解释
问题是 : 为什么String类要设计成final?回答在单独的一个笔记片里。
 
 
时间:2017年4月24日17:03:32
章节:02章_递归的补充
视频长度:4:17+8:52+6:15+1:43+10:18+2:30
内容:关于递归的介绍与讲解
心得:
 
public static void main(String[] args) {
    System.out.println(method(4));
}
 
public static int method(int n) {
    if (n == 1) {
        return 1;
    } else return n * method(n - 1);
}

需要注意的是 一个方法只有运行结束了才会return 
那么对于递归,可以理解成多重调用自己,多层嵌套,直到所有方法运行结束
如上面这个例子
method(4) --> return 4*method(3) --> return 4*3*method(2)
依次类推
 
例子:斐波那契数列
1,1,2,3,5,8,....40
就是第N个数的是第N-1和第N-2数的和,(第1和第2个数字都是1)
递归是解决的一种办法之一
 
//该方法输入斐波那契数列的第几个数,返回改数的数值
public static int f (int n){
     if(n == 1 || n == 2){
          return 1;//第一个数和第二个数是1
     }else{
          return (f(n-1) + f(n-2));//否则的话就是前2个数的和
     }
}
 
课堂练习:用其他方法解决这个问题
第一反应:用循环构造一个这种数列试试
 
public  static  int x (int n){
    int[] array = new int[n];
      //对于数组里的数值依次赋值,首先构造出这种数列,然后返回相应的值
    for (int i = 0; i <array.length ; i++) {
        if (i == 0 || i == 1){
            array[i] = 1;
        }else {
            array[i] = array[i-1] + array[i-2];
        }
    }
    return  array[n-1];
}

 
另外的解决办法:利用for循环直接构造3个数,也就是用户需要返回的数值,以及整个数的前面2个数,毕竟斐波那契数列 的任何一个值单单来看的话只和他前2个数挂钩(相加),因此只要不断地更新这3个数就可以了
 
    /**
* 另一种思路,直接利用循环构造,也是视频里老师的解决方法
* @param index
* @return
*/
public  static long f2(int index){
    //第1个和第2个是1
    if (index == 1 || index ==2){
        return  1;
    }
    //从第3个数开始进行构造,默认第1个数f1是1,第二数f2也是1
    //f是最终要输出的数
    long f1 = 1L;
    long f2 = 1L;
    long f = 0;
    //因为是从第3个开始的,所以构造次数要-2(减掉第1个数和第2个数,已经给了默认值了)
    for (int i = 0; i <index-2; i++) {
        f = f1 + f2;//f是前面2个数的和
        f1=f2;//对f1,f2进行更新,因为f1,f2指的是用户想要的数f的前2个数,所以根据循环构造的情况要不断更新
        f2=f;
    }
    return f;
}

 
第二章结束时间:2017年4月24日17:49:13
 
总结,便于复习时使用
技术分享

 

Java基础知识二次学习-- 第二章 基础语法与递归补充