JAVA基础入门
Java se 基础版 核心
结算系统 桌面游戏 桌面软件
java ee 企业版
大型系统 大型网站
Java me (被淘汰)移动版 安卓/iOS
Java是一个跨平台语言:一次编写 处处运行(不同操作系统)
Java能够跨平台原因:有各种类型的jvm(虚拟机),且各个jvm不跨平台
写代码(Java) -> 编译(class) -> 执行class
jvm(Java virtual machine):
Java虚拟机
jre(Java运行环境 Java runtime environment):
jvm + 核心类库
只能运行Java程序,但不能开发
jdk(Java development kit):
jre + 运行环境工具
既能运行Java程序,又能开发
jvm < jre < jdk
开发人员需要下载并安装jdk8u192以前的版本
安装目录只能用英文数字下划线,其他都不可写,否则可能出错
安装jdk时会自动提示安装jre(可选择安or不安)
配置环境变量(大小写不区分)
java_home :jdk的根目录 C:\Program Files\Java\jdk1.8.0_221
path(必须,原系统有,在最前面加上):;C:\Program Files\Java\jdk1.8.0_221\bin;
classpath: .;C:\Program Files\Java\jdk1.8.0_221\lib
java语言区分大小写
第一个java代码
写代码(.java) ->编译(.class,字节码,相当于二进制可直接被计算机运行)->执行class
换盘 f:
进入文件夹 cd 文件名
编译命令: javac 文件名.java
执行 : java 文件名 (没有.java)
public class Test
{
public static void main (String[] args)
{
System.out.println("hello world");
}
}
1.class后面的称之为“类名”
2.public class后面的类名 必须和文件名保持一致
3.一个文件可以多个类(class),但是只能有一个 公共类(public class)
4.System.out.println(“hello world”);输出语句
5.分号是每条语句的结束符(程序中的一切符号都是半角英文)
6.各种括号成对出现,注意缩进
7.程序的入口就是main()方法
(其他语言称之为 函数)
System.out.print();不带回车的输出语句
System.out.println();带回车的输出语句
转义符\n
System.out.println(“aa\na”);先执行()中的各种操作,最后再ln回车
\t :制表符
补满一定位数(cmd中8位)
如果在.java文件中有汉字,并且在javac编译时出现了错误提示“错误:编码GBK的不可映射字符”
解决:将文件的编码改为ANSI码
注意java采用的默认字符编码集是Unicode(16byte)
注释
//
/……/ 不能嵌套
/*…/ 文档注释:将程序生成一个说明文档,说明文字由此生成
工具
Eclipse
IDEA(推荐)
create new project -> 选择本地jdk -> 无脑下一步(项目名)
src右键 -》 new -》class-》输入类名
改字体大小:file-》settings-》general-》font
快捷键
main快捷写法:psvm+tab 敲main试试<br /> 输出语句: sout+tab<br /> 运行:右键run<br /> 单行注释:ctrl+/<br /> 多行注释:Ctrl shift /
变量应用
变量存在于内存中(程序结束、计算机关机之后 变量失效)像宾馆
java数据类型:
引用数据类型(对象类型):<br /> <br /> String ...字符串(放任意字符且用双引号“”引起来)<br /> 原生数据类型(基本数据类型):8<br /> 整数:byte < short < int < long<br /> 小数:float < double <br /> 整数默认int 小数默认是double<br /> 一般原则:尽量使用 最小范围<br /> 字符:char :只能放一个字符且用单引号‘’引起来<br /> 布尔:Boolean
计算机二进制:0 1(连通 断开)
字节 byte = 8bit (-128 — 127)
短整数 short = 2byte
整数 int = 4byte
长整数 long = 8byte
float = 4byte
double = 8byte
float xx = 123.4**; 是错的**
解决方法:
float xx = 123.4f;
float xx = (float)123.4;
但整数不会出现这种情况,因为整数自带(整数类型)转换器
变量名可以代替变量值
变量区分大小写
使用 局部变量 前必须赋初值
java可以直接表示的进制
二进制: 0b数字 0b11表示3
八进制: 0数字 011 9
十六进制:0x11 A-F 10-16
命名规则:驼骆峰
变量名强制规则:
首字母 + 其他
首字母:各国语言,下划线,钱¥
其他: 首字母 + 数字(不能在首字母里面)
不能是关键字(idea中蓝色字体)
符号只能是下划线、钱
变量范围:最近一对大括号{}
输出变量,括号里的变量不能加双引号,否则只会打印出变量名,而非变量值
+ :拼接
输入Scanner
自动导包问题
开启file-settings-Editor-auto import-全部勾上<br /> 如果没有自动导入,可能该类在当前环境中重名。需要手工导入<br /> 光标放到Scanner后面,alt+回车<br />默认包:java的默认包是java.lang,即该包中的所有类会被自动导入,因此不用写import...
输入方法/格式
Scanner中有很多类型的输入方法,但没有接受char的方法
从控制台输入:
Scanner input = new Scanner(System.in);
input.nextXxx();
int javaScore = input.nextInt();
接收各种类型(除了char)
字符串:next()/ nextLine()
String name = input.next();
String name = input.nextLine();
next()/ nextLine()区别
next():
- 1、一定要读取到有效字符后才可以结束输入。
- 2、对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。
- 3、只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
- 4、next() 不能得到带有空格的字符串。
nextLine():
public class ScannerDemo { public static void main(String[] args) { Scanner scan = new Scanner(System.in); // 从键盘接收数据
// next方式接收字符串
System.out.println("next方式接收:");
// 判断是否还有输入
if (scan.hasNext()) {
String str1 = scan.next();
System.out.println("输入的数据为:" + str1);
}
scan.close();
}
} 输出: next方式接收: runoob com 输入的数据为:runoob
<a name="lUoDt"></a>
### nextLine方法
```java
import java.util.Scanner;
public class ScannerDemo {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
// 从键盘接收数据
// nextLine方式接收字符串
System.out.println("nextLine方式接收:");
// 判断是否还有输入
if (scan.hasNextLine()) {
String str2 = scan.nextLine();
System.out.println("输入的数据为:" + str2);
}
scan.close();
}
}
输出:
nextLine方式接收:
runoob com
输入的数据为:runoob com
Scanner的hasNext()方法
import java.util.*;
public class ScannerKeyBoardTest
{
public static void main(String[] args)
{
System.out.println("请输入若干单词,以空格作为分隔");
Scanner sc = new Scanner(System.in);
while(sc.hasNext())
{
System.out.println("键盘输入的内容是:"
+ sc.next());
}
System.out.println("执行吗");
}
}
执行到hasNext()时,它会先扫描缓冲区中是否有字符,有则返回true,继续扫描。直到扫描为空,这时并不返回false,而是将方法阻塞,等待你输入内容然后继续扫描。这样的话,它岂不是吃了**口香糖根本停不下来。
让我们来改一改代码试试?
import java.util.*;
public class ScannerKeyBoardTest
{
public static void main(String[] args)
{
System.out.println("请输入若干单词,以空格作为分隔");
Scanner sc = new Scanner(System.in);
while(!sc.hasNext("#")) //匹配#返回true,然后取非运算。即以#为结束符号
{
System.out.println("键盘输入的内容是:"
+ sc.next());
}
System.out.println("会执行的!");
}
}
hasNext()和hasNextLine()方法的区别
hasNext()
方法会判断接下来是否有非空字符.如果有,则返回true
,否则返回false
hasNextLine()
方法会根据行匹配模式去判断接下来是否有一行(包括空行),如果有,则返回true
,否则返回false
比如当前我们有如下测试用例:
7 15 9 5
• 1
这个测试用例在牛客网上是以文件的形式进行存储的.
而在 linux 系统中文件的结尾会有一个换行符\n
,也就是说从System.in
输入流中真正读取到的数据流是这样的:
7 15 9 5\n
• 1
程序在处理完5之后,输入流中就只剩下一个换行符\n
了,在处理完5之后while再去进行循环判断,此时hasNext()
方法和hasNextLine()
方法去判断得到的结果就产生了差异.
hasNext()
方法会认为之后再没有非空字符,会返回一个false
hasNextLine()
方法会认为换行符\n
是一个空行,符合行的匹配模式,则会返回一个true
,但实际上由于之后再没有数据了,所以会在读取输入流的时候发生异常,从而导致整个运行报错.建议方案:
采用
hasNextXxxx()
的话,后面也要用nextXxxx()
:比如前面用
hasNextLine()
,那么后面要用nextLine()
来处理输入;- 后面用
nextInt()
方法的话,那么前面要使用hasNext()
方法去判断.
阅读异常
数据类型的转换
1.自动转换
范围小的类型,可以自动转换(赋值)为范围大的类型<br /> 范围小的类型 遇到 范围大的类型,自动转为范围大的<br /> int a = 10 +3.14; int = double ×<br /> 整数<小数<br /> “最大是字符串”:任何类型遇到字符串,自动转为字符串<br /> char < int<br /> java默认Unicode编码(Unicode兼容于ASCII)<br /> <br />
2.强制转换
范围大的 赋值给 范围小的 必须强制转化<br /> 通用写法:<br /> 范围小 = (小类型)范围大;<br />特殊:<br /> float f = 1234.5**f**** **;
关系(比较)运算符
字符串 相等 equals()
比较运算符结果:布尔值
运算符优先级不用背:不清楚用括号括起来
变量:num
表达式:num * 122
两数交换:中间变量、加减法(溢出问题,不建议)、位运算(效率最高)
中间变量:t两边写,变量xy分别抄两遍
t = x;
x = y;
y = t;
int max = Integer.MAX_VALUE; //int最大值
改变联想词设置:
settings -> general -> code compelete -> 默认First letter 不要的话把最前面的√勾掉
最大值+1 = 最小值 底层是个循环
%求余:正负结果永远与被除数一致
System.out.println(-10%-3); //-1
逻辑运算
有短路特性
&&且
||或
没短路特性,全部都判断一遍
&
|
+= 加号
=+ 正号
i++ 先用后加
i 先加后用
int i = 10;
System.out.println(i) ; //10 先用:输出10.后加,到后面i变为11
System.out.println(i++) ; //10
System.out.println(i++) ; //11
System.out.println(i) ; //12
整数 = += 有内置转换器
byte b1 = 100;
byte b2 = 100;
// b2 = b1 + b2 × 特例:byte int的整数情况(特殊),byte+byte,short+short -> int
// byte = byte + byte ; ×
// byte += byte √ 整数 = += 有内置转换器
判断字符转相等equals
String str1 = "abc";
String str2 = "abc";
System.out.println(str1.equals(str2)); //true
三目运算符
1?2:3;
System.out.println(3 * 0.3f); 运算结果 0.899999999999999
float\int : 32bit
int范围能容纳下 2的32次方 个数字
float的小数,无穷无尽个数字,因此2的32次方个位置 无法容纳所有小数
深入理解:二进制
所有的整数都能用二进制来表示 5=2(0)+2(2)
但不是所有的小数都能用二进制表示 0.6
if /switch
java语言的if(表达式),表达式只能是布尔值,不能使01 和C不一样
if判断Boolean 是or不是 一般用flag == true 这种判断
随机数
Math.random(); ** **// [0,1)
switch后支持的表达式类型:
int short byte char String 枚举…
case后面的值 必须是常量
一般不建议冷略break 但个别情况可以省
排名前三的奖励问题
double ran = Math.random();
System.out.println(run);
//三位随机数
System.out.println((int)(Math.random()*900) + 100);
//[0,1) *900 -> [0,900) +100 -> [100,999)
int rank = 2;
switch(rank){
case 1:
System.out.println("笔记本");
break;
case 2:
System.out.println("U盘");
break;
case 3:
System.out.println("夏令营");
break;
default:
System.out.println("不奖励");
break;
}
switch会用 rank和所有的case匹配 如果匹配成功 则执行相应case后的语句 直到break结束
在switch中 如果rank和所有的case都不匹配 则执行default
//判断大月
System.out.println("请输入月份");
Scanner input = new Scanner(System.in);
//if(是否是数字)
if(input.hasNextInt()){ //input.hasNextDouble() Next后面是啥类型就判断啥类型
int month = input.nextInt(); //Ctrl Alt L 格式化
switch(month){
case 1:
case 2:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
System.out.println("是大月");
}
}else{
System.out.println("请输入数字!");
}
多重if和switch的区别
如果判断的是 区间值 多重if
如果是离散/单点值 switch
do…while
do{
System.out.println(“是大月”);
}while(1>2); **//注意分号必须写!**
//数字倒叙输出 12345
找规律
int num = 12345;
int rear = -1; //每次打印的数值
num = num * 10; //因为要补第一次的 /10
//5
num = num / 10; //凑循环
num = num % 10;
System.out.println("rear");
//4
num = num / 10;
num = num % 10;
System.out.println("rear");
//3
num = num / 10;
num = num % 10;
System.out.println("rear");
// 2 1
while(num / 10 > 0){ // /10 因为前面*10 如果不/10 最后会输出一个0
num = num / 10;
num = num % 10;
System.out.println("rear");
}
break /continue
break 终止循环
continue 跳过当前循环
//万年历 星期n = days % 7
import java.util.Scanner;
public class Mycalender {
public static void main(String[] args) {
//已知1900.1.1 Monday
//输入年、月(2019.10)-> 系统自带打印当月月历
//第一步 要知道当月1号是周几
/*
日期a 天数b 星期c 中间量b
1900.1.1 1 1
1900.1.2 2 2
1900.1.3 3 3
1900.1.4 4 4
1900.1.5 5 5
1900.1.6 6 6
1900.1.7 7 0
1900.1.8 8 1
1900.1.9 9 2
1900.1.10 10 3
1900.1.11 11 4
1900.1.12 12 5
1900.1.13 13 6
1900.1.14 14 0
2019.10.1 -> a-b
a -> c c -> b => a -> b
a -> b : 星期n = 天数 % 7;
a -> c : 哪一日(2019.10.1) 是第几天
1900.1.1 - 2019.10.1
分为:1900-2018 整个年份包含天数
2019.1 - 2019.9 整个月份 +1 -> 2019.10.1
*/
Scanner input = new Scanner(System.in);
System.out.println("请输入年份:");
int year = input.nextInt();
System.out.println("请输入月份:");
int month = input.nextInt();
// int year = 2049;
// int month = 3;
int days = 0;
//1900-2018
for(int i=1900 ; i<year ;i++){
//一个年份可以被4整除,且不能被100整除;
// 或一个数字能被400整除
if((i%4==0 && i%100 != 0 )|| i%400==0)days += 366;
else days += 365;
}
//2018.12.31.
//2019.1.1 - 2019.9.30
for(int i=1;i<month;i++){
switch(i){
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
days += 31;
break;
case 4:
case 6:
case 9:
case 11:
days += 30;
break;
default:
if ((year%4==0 && year%100 != 0 ) || year%400==0){
days += 29;
}else{
days += 28;
}
}
}//2019.9.30.
days++;//2019.10.1.
int xingQi = days % 7;
System.out.println(year+"年"+month+"月一号是星期" +xingQi);
System.out.println("星期日\t星期一\t星期二\t星期三\t星期四\t星期五\t星期六\t");
//根据观察:星期n前面有n个空格(占位符)
//占位符个数就是星期n
for(int i=0;i< xingQi ;i++){
System.out.print("\t\t");
}
//定义当月有多少天
int daysOfMonth = -1;
if (month == 1 ||month == 3 ||month == 5 ||month == 7 ||month == 8 ||month == 10 ||month == 12){
daysOfMonth = 31;
}else if (month == 4 ||month == 6 ||month == 9 ||month == 11){
daysOfMonth = 30;
}else{
if ((year%4==0 && year%100 != 0 ) || year%400==0){
daysOfMonth += 29;
}else{
daysOfMonth += 28;
}
}
//当月天数
for (int i=1;i<=daysOfMonth;i++){
System.out.print(i+"\t\t");
if ((xingQi + i)%7==0)
System.out.println(); //回车
}
}
}
思路:
已知1900.1.1 -> Monday
2019.10.1 是星期几 -> 星期n = 天数 % 7 ; -> 2019.10.1是第几天(1900.1.1是第一天) 整年+整月
整年 1900-2018 :365/366
整月 2019.1 - 2019.9 :30/31/29/28
星期n = 天数 % 7;
星期n前面有n个占位符 (注意占位符大小)
数组
三种声明
eg1:
int data[]=null; //声明数组
data = new int[3] ; //分配内存
eg2:
int data[] = new int[10] ;
简化大量数据处理
- int[] students = new int[300] ;
- int students[] = new int[300] ;
使用
四要素
- 数组名
- 下标
- 类型
- 数组元素
数组的类型 和 数组元素的类型 一致 (兼容)
三人成绩和
import java.util.Scanner;
public class Test2 {
public static void main(String[] args) {
int[] students = new int[3];
int sum = 0;
Scanner input = new Scanner(System.in);
for (int i=0;i<3;i++){
System.out.println("请输入第"+(i+1)+"个学生的成绩:");
students[i] = input.nextInt();
sum += students[i];
}
System.out.println(sum);
}
}
什么时候用数组
数组定义
- //只声明数组的元素个数,但不赋值(默认值)
int[] students = new int[3];
- //只赋值 但不声明元素个数
int[] students =new int[]{97,98,99};
- //理解为2的简化,不能拆开编写
int[] student = {97,98,99} ;
数组的长度(元素的个数)
数组作为一种引用类型,拥有自己的一些方法和属性,其中int类型的length属性可以得到数组的元素个数
数组名.length
数组的最后一个:数组名.length - 1
例题
有一个数列: 8 4 2 1 23 100 12<br /> 1.求和<br /> 2.随机产生一个1-3之间的数,判断数列中是否有此数<br /> 3.排序,输出结果
public class Test3 {
public static void main(String[] args) {
//求和
int[] nums = {8,4,2,1,23,100,12};
int sum = 0;
for(int i=0;i<nums.length ;i++){
sum += nums[i];
}
System.out.println(sum);
//2.随机产生一个1-3之间的数,判断数列中是否有此数
int ran = (int)(Math.random()*3+1);
//[0,1) -> [0,3) 0-2 -> +1 -> 1-3
System.out.println("随机数是:"+ran);
boolean flag = false;
for(int i=0;i<nums.length;i++){
if(ran == nums[i]){
flag = true;
break;
}
}
if(flag){
System.out.println("存在");
}else{
System.out.println("不存在");
}
//3.排序,输出结果 小到大
int t;
for (int i=1;i<nums.length;i++){
if(nums[i-1]>nums[i]){
t = nums[i-1] ;
nums[i-1] = nums[i];
nums[i] = t;
}
}
for (int i=1;i<nums.length;i++){
System.out.println(nums[i]+"\t");
}
}
}
排序的快速语法
Arrays.sort(p);
small->big
p是一个数组名
//定义一个数组double[] score = new double[n];for (i=0;i<n;i++){
//输入n个成绩 score[i]=input.nextDouble();}
//由小到大排序Arrays.sort(score);
给67 87 88 98 99 数组中 插入一个元素 insert 保持从小到大的顺序(不可用排序算法)
public class Test4 {
public static void main(String[] args) {
int[] nums = new int[]{67,87,88,98,99};
//创建新数组,能够容纳新插入后的 全部元素
int[] newnums = new int[nums.length+1];
for(int i=0;i<nums.length;i++){
newnums[i] = nums[i];
}
int insert = 1000;
//位置
int postion = newnums.length-1;//默认插入位置是最大值位置
for (int i=0;i<newnums.length;i++){
if(newnums[i]>insert){
postion = i;
break;
}
}
System.out.println("位置:"+ postion);
//平移 插入位置 postion - newnums.length-2
for (int i=newnums.length-2;i>=postion;i--){
newnums[i+1] = newnums[i] ;
}
//插入
newnums[postion] =insert;
System.out.println("查看新数组:");
for (int i=0;i<newnums.length;i++){
System.out.println(newnums[i]);
}
}
}
遍历数组,for的另一种的写法
for(元素类型 变量名:数组)
变量名 相当于 nums[i]
public class Test5 {
public static void main(String[] args) {
int[] nums = new int[]{33,2,1,2,455};
// for (int i=0;i<nums.length;i++){
// System.out.println(nums[i]);
// }
//
for (int x:nums){ //变量名 x 相当于nums[i]
System.out.println(x);
}
}
}
例题:抽奖游戏
1.注册2.登陆3.抽奖
注册时 系统会自动生成一个4位随机数作为卡号
登陆成功即可抽奖
抽奖时系统生成6个4位随机数作为幸运数字
如果会员卡号是其中之一,则成为本日幸运会员,否则不是会员
import java.util.Scanner;
public class Test6 {
public static void main(String[] args) {
//注册
System.out.println("注册");
String reqistName = "";
String reqistPwd = "";
Scanner input = new Scanner(System.in);
System.out.println("请输入用户名:");
reqistName = input.next();
System.out.println("请输入密码:");
reqistPwd = input.next();
System.out.println("注册完毕..");
int vipNum = (int)(Math.random()*9000)+1000; //随机四位
System.out.println("登陆");
String loginName = "";
String loginPwd = "";
System.out.println("登陆用户名");
loginName = input.next();
System.out.println("登陆密码");
loginPwd = input.next();
if (loginName.equals(reqistName) && loginPwd.equals(reqistPwd)) {
System.out.println("登陆成功");
System.out.println("抽奖");
//产生6个幸运号码
int[]luckyNums = new int[6];
for (int i=0;i<6;i++){
luckyNums[i] = (int)(Math.random()*9000)+1000;
System.out.print(luckyNums[i]+"\t");
}
System.out.println("你的vipNum"+vipNum);
boolean flag = false;
//判断VIPNum 是否存在于luckyNums之中
for (int i=0;i<6;i++){
if (vipNum==luckyNums[i]){
flag = true; //中奖
break;
}
}
if (flag){
System.out.println("中奖");
}else {
System.out.println("没中奖");
}
}else{
System.out.println("用户名or密码输入有误!");
}
}
}
二维数组
int[][] ums = { { 1,2,3 } , { 2,3,4 } , { 5,6,7 } } ;
声明及实例化
int data [][] = new int[4][3] ;
静态初始化
int data[][] = {{1,2},{3,4}} ;
异形数组
int data[][]=new int[3];
data[0]=new int[2];
data[1]=new int[3];
data[2]=new int[1];
二维数组行列数 length运用
data.length
data[i].length
例题:省份中的城市
public class ProvinceCities {
public static void main(String[] args) {
String[] provinces = {"陕西","山西","四川"};
String[][] cities = {
{"山西", "咸阳", "渭南"},
{"太原", "运城", "大同"},
{"成都", "都江堰", "广元"}
};
// System.out.println(cities[1][1]);
// System.out.println(cities[1][2]);
String p = "陕ddd西"; //输入需要判断的省份
int position = -1;
boolean flag = false;
for (int i=0;i<provinces.length;i++){
if (p.equals(provinces[i])){
position = i;
flag = true;
break;
}
}
if (flag){
//要打印的二维数组的行号i
for (int j=0;j<cities[position].length;j++){
System.out.println(cities[position][j]);
}
}else {
System.out.println("输入有误");
}
}
}