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)

  1. public class Test
  2. {
  3. public static void main (String[] args)
  4. {
  5. System.out.println("hello world");
  6. }
  7. }

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

快捷键

  1. 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():

  • 1、以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符。
  • 2、可以获得空白。

    next方法

    ```java import java.util.Scanner;

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("执行吗");
    }
}

image.png

执行到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("会执行的!");
    }
}

image.png

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个占位符 (注意占位符大小)

数组

三种声明

image.png

eg1:

int data[]=null; //声明数组
data = new int[3] ; //分配内存
image.png

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);
    }
}


什么时候用数组

当多个元素类型相同,考虑用数组

数组定义

  1. //只声明数组的元素个数,但不赋值(默认值)

int[] students = new int[3];

  1. //只赋值 但不声明元素个数

int[] students =new int[]{97,98,99};

  1. //理解为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];
image.png

二维数组行列数 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("输入有误");
        }


    }
}