Java-SUN
语言平台J2SE(桌面) ,J2ME(移动被安卓所取代),J2EE(企业主要用于web)
1.跨平台(操作系统)原理:
在任意操作系统上运行,一次编写到处运行。
依赖JVM(Java Virtual Machine)(不同系统Windows,Linux,mac有自己对应的JVM)
2. JRE和JDK
In a word,使用JDK开发完成的Java程序交给JRE运行
JRE(Java运行环境Java Runtime Environment)
包括JVM和Java程序所需的核心类库等,如果想要运行一个开发好的Java程序,只需安装JRE就好了。
JDK(Java开发工具包)
让Java开发员使用的工具,包括了JRE(所以安装了JDK就不需要单独装JRE了)其中的开发工具包扩编译工具和运行工具。
3. 程序运行的流程
源文件program.java--------编译器------字节码文件program.class------解释器-------(能让机器识别的101001001001)program
4.注释
--单行注释: // .........
--多行注释 : /* ........... */
--文档注释 : /** ............ */
5.关键字
Java中特定含义的字符
特点:
1.组成关键字的字母全部小写
2.常见的代码编辑器对关键字有特殊颜色的标记。
例如:class,new,this等
6.变量和常量
变量
(内存中最小的容器)
内存中的一小块区域:在程序执行的过程中,在某个范围内值可发生改变
局部变量(方法体内部)和成员变量(类属性字段)
组成:
1.对区域要有限定:数据类型
2.区域要有名称:变量名
3.区域必须有内容:初始化值
数据类型 变量名=初始化值(int a=0;)
常量
final 数据类型 变量名=值
7.计算机存储单元
·无论内存还是硬盘,计算机存储设备的最小信息单元是 位(bit)(又叫比特位),用b表示
·计算机最小的存储单元是 字节(byte),用B表示
(通常1个字节由连续的8个位表示)
8.数据类型
数据类型由基本数据类型(值)和引用数据类型构成。(地址和引用)
1.基本数据类型(值)有四类八种
基本数据类型(值) | 所占字节 |
---|---|
数值型(整型(byte,short,int,long) | 分别占用1.2.4.8字节 |
数值型(浮点型(float,double)) | 分别占用4,8字节 |
字符型(char)) | 占用2字节 |
布尔型(boolean)构成true 或false | 占用1字节 |
科学计数法E
注意:
(1)整型默认类型是int,浮点型默认double
(2)定义long类型数据时要加L或l,建议加L;
例如:long l=100000000000000L;
不加L可能报错,数字过大;(因为默认是int,而int只有四个字节)
(3)定义float类型数据时要加F或f,建议加F。
例如:float f=12.34F
不加F可能报出损失精度;(因为默认是double,double有八个字节,要说明float的四个字节则用F标记出来)
2.引用数据类型
引用数据类型有类class | |
---|---|
类class | |
接口interface | |
数组[] |
9标识符
给包,类,方法,变量等起名字
组成规则:由字符,下划线_,美元符$组成
注意:
(1)这的字符是Unicode字符集,包含英文大小写字母,中文字符(但一般不建议用汉字)和数字
(2)不能以数字开头
(3)不能是Java中的关键字
命名规则:见名知意
--常见规则
·包(文件夹)
全部小写,多级包名用点隔开; 如com.edu.demo
·类
一个单词的首字母大写;如StudentCat
多个单词,每个单词首字母大写,如HelloWorld
·变量/方法
一个单词首字母小写,如age.show();
多个单词,从第二个单词开始每个单词首字母大写maxAge.getAge(),或者setAge
10变量的定义和使用
·八种基本数据类型变量的定义
byte b=10;
short s=100;
int i=100;
long l=10000000000L;
float f=12.34F;
double d=12.34;
char c='s';
boolean bol=true;
·注意事项:
(1)变量未赋值,不能直接使用
即要使用(操作)之前,必须要有值;
(2)变量只在其所属范围(即所属的那对大括号)内有效
{int c=50;
}
System.out.println(c);
会报错,找不到c
(3)可以在同一行定义多个变量
int a,b;
a=0;
11类型转换
1.运算
------运算符
赋值 =
关系运算符> < >= <= == !=
逻辑运算符 && || !
算数运算符+ - * % / ++ --
整数除以整数得到整数
关于加加减减:
a++表示先使用(操作)a再加加
a=10
int b=a++
结果:b=10;a=11
(先使用a(赋值给b),再对a加加)
++a表示先加加再使用a
a=10
int b=++a
结果:b=11;a=11
(先对a加加,再使用a(赋值给b))
------一般要求参与运算的数据的类型必须一致
但是举一例子如下
byte b=1;
int a =3;
System.out.println(a+b);
明显结果是可以输出的,a+b所得类型是可以接受的
思考:一般而言要求相加类型一致,而此处不一致why?又用什么类型来接收呢?
回答:
byte c=a+b; 报错
int c=a+b;可以直接输出
若用byte来接收会报错(损失精度);但用int 类型来接收就可以了
这就引出了一个问题-----类型转换
2.隐式转换
含义:若有长字节的类型数据参与运算时,先转换成长字节类型参与运算,因为长字节可以接受短字节,但短字节不能接受长字节
即所谓默认转换-----短字节可以自动默认转换成长字节
顺序如下:
------byte,short,char--->int--->long--->float--->double
举例:byte,short,char之间不能相互转换,参与运算首先转化为int类型
换句话说,即byte,short,char三种类型数据参与运算时,可以直接输入结果,但若用其他类型数据来接收时,应用int类型
byte a=1;
char b=2;
int c=a+b;
print(c);用整型来接收并输出是可行的或者直接输出a+b也可。
3.特别注意boolean类型不能转换为其他数据类型
4.强制转换
------目标类型 变量名 = (目标类型)(被转换的数据)
举例:
byte b=10;
int a=20;
int c=a+b;
明显此处作了一个类型提升,但是我们发现c=30,而明显byte范围内即可表示,但是默认(隐式)转换成了int
自然也可以强转成byte:byte c=(byte)(a+b)
但是建议:数据运算结果,应该是什么类型,就用什么类型接收,不要随意强转,可能会损失精度
12分支循环
分支 : if单分支;switch case分支
if:if-else;if-else if
if(表达式){}
注:
1.表达式布尔boolean类型
2.if-else if 多个条件 条件只会执行一个
输入一个数判断当前数偶数奇数3的倍数 分别输出
switch case:
相当于if--else if
switch(常量){
case 条件:执行语句; break;
default: 执行语句; break;
}
注释:常量是一个泛指int char String 枚举
break可以省略-->贯穿
case 条件1:
case 条件2:执行语句 break;
表示条件1,2都执行同一句
break表示结束当前所在循环,continue表示跳出本次操作,但仍在循环中
EXIT:for i 循环
...........for j循环
...............if条件 beak EXIT;
操作;
结果: if条件满足后,退出(结束)整个双重循环
若没有EXIT:if条件满足后。退出当前j循环。仍在i循环内继续i++
若为continue:if条件满足后。退出当前 j 循环的本次操作。仍在 j 循环内继续j++
循环:
- while(0.1%) do-while for(99.9%最常用)
- 循环变量赋初值 int i
- 循环条件 关系或逻辑表达式
- 循环变量自增自减 ++ -- /= %=
- 循环体
13 方法(类的内部)
访问权限修饰符 其他修饰符 返回值类型 方法名(参数列表){
方法体;
ps:有返回值类型的必须添加return
ps: 若void不必添加
}
返回类型
静态方法:本类直接调用,其他类中访问添加类名
无返回值的方法一定不能接收,有返回值的有选择结收
只要能通过输出语句打印出来的都是有返回值的
递归:能不用就不用,初级递归都可以用循环解决(高级不行)
递归一定要有出口
递归太影响性能
数组(引用类型)
1.定长 声明书组有多长就是多长
2.定义时候指明存储类型
- 使用的是下标 从0开始 到 当前数组长度-1结束
int[] arr=new int[10]
整数默认值是0
浮点型默认值是0.0
char默认值空字符不可见
boolean默认值false
引用类型 默认值是null
#######数组有length属性
数组名[下标值] 数组的长度arr.length
数组中数据元素的数据类型:整型int
数组的数据类型:int[]
可以试试:
int [] arr=new int[10];
public int[] display(){
return arr;
}
介绍:Math.random()100
这是一个左闭右开的区间[0,1)100-->表示从0到99,,是浮点型用于int要强转
for (int i=0;i<10;i++){
int arr[i]= (int)(Math.random()100);
}
介绍
for (int i=0;i<10;i++){
int arr[i]= (int)(Math.random()100);
}
for(int i: arr)
{i=10;
System.out.prinln(i);}
表示随机打印十个数
注这个 方法只能打印,增强for循环不能修改值
相当于得到新数组ai,并将arr数组给ai赋值,遍历的是新数组ai,再循环体内有一个变量i获取的是新数组ai的值
排序
冒泡:
趟数,每一趟将较小数冒出,大数沉底。(每次会找到数的合适位置)
for(int i= 0 ;i<arr.length-1;i++) {
for(int j = 0 ; j<arr.length-1-i;j++) {
if(arr[j] > arr[j+1]) { //升序 从小到大 > 降序从大到小 <
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
选择:
固定一个标志位,比较大的交换小的不变
for(int i= 0 ;i<arr.length;i++) {
for(int j = i+1 ; j<arr.length;j++) {
if(arr[i] > arr[j]) { //升序 从小到大 > 降序从大到小 <
//交换
}
}
}
工具类 默认是升序 ,需要实现接口
Arrays.sort(arr);
//不用二维数组
二分(择半)查找(致命缺点:对有序序列进行查找)
***理论上的二分查找(假设已经排好序且无重复值)
//数组开始值+length=sum
*middle=sum/2
*low=数组第一位下标0
*end=数组长度-1
*middle与key进行比较
*key大右边去差 start=middle+1
*key小左边去查 end=middle-1
*重新计算middle//
线性查找(对随机序列进行查找遍历)
寻路算法
单例模式
懒汉和饿汉模式
两者都需
<1>都需私有化构造方法
<2>
懒汉:需要一个私有的静态的当前类类型的属性
饿汉:需要创建一个私有的静态的当前类类型的属性并进行赋值
<3>
懒汉:提供一个公有静态方法
然后在方法中对当前属性进行判断是否为null
若为null 就创建对象然后返回值
若不为null 就直接返回
饿汉:
//线程
简单版
class A{
}
枚举enum
可以定义方法,属性,也能继承
public enum Demo{ INSTANCE}
字符串类型
Java 平台提供了两种类型的字符串:String 和 StringBuffer/StringBuilder,它们可以储存和操作字符串。
其中 String 是只读字符串,也就意味着 String 引用的字符串内容是不能被改变的。而 StringBuffer/StringBuilder 类表示的字符串对象可以直接进行修改。
String: 一个不可变字符串,有length()方法
JDK源码定义了String的对象不可变和线程安全
final类型不可被继承,对象不可变
String str=“abc”//字符串池中有一个abc,str指向她
str=“bcd”//字符串池中新建一个bcd,str指向bcd
所以说没有在原有空间内将abc删除后重新赋值
String str2=“abc”//再一次创建abc时,并没有创建而是在池中找有没有abc这个串,若有str2指向它
String str3=new String(“abc”)//str3是new出来的,在堆中而不是池中
StringBuffer和StringBuilder:可变字符串,操作的是对象本身
有公共父类AbstractStringBuilder(抽象类)
String str=abc;
str+"a";语法是错误的,必须要有返回类型
String str2=str+“a”;正确
而对于StringBuilder
StringBuilder str=new StringBuilder(“abc”);
str.append("a");
输出结果abca
线程安全String和StringBuffer
线程不安全StringBuilder
数据量小直接用String
数据量大单线程StringBuilder
数据量大多线程StringBuffer