欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java学习记录1

程序员文章站 2022-05-28 18:36:28
...

2020年10.25-10.31日

一、Java入门

为什么要学Java?因为Java是全球排名第一的编程语言,Java工程师也是市场需求最大的软件工程师,选择Java,就是选择了高薪。
为什么Java应用最广泛?
从互联网到企业平台,Java是应用最广泛的编程语言,原因在于:

为什么Java应用最广泛?

从互联网到企业平台,Java是应用最广泛的编程语言,原因在于:

  1. Java是基于JVM虚拟机的跨平台语言,一次编写,到处运行;
  2. Java程序易于编写,而且有内置垃圾收集,不必考虑内存管理;
  3. Java虚拟机拥有工业级的稳定性和高度优化的性能,且经过了长时期的考验;
  4. Java拥有最广泛的开源社区支持,各种高质量组件随时可用。

Java语言常年霸占着三大市场:

  1. 互联网和企业应用,这是Java EE的长期优势和市场地位;
  2. 大数据平台,主要有Hadoop、Spark、Flink等,他们都是Java或Scala(一种运行于JVM的编程语言)开发的;
  3. Android移动平台。
  4. 这意味着Java拥有最广泛的就业市场。

在这里说一句,我是学了一段时间的算法(ML和DL方向),看到实验室的师兄师姐今年找工作都是找的开发,算法都不太好找工作,过段转开发了。

随着Java的发展,SUN给Java又分出了三个不同版本:

Java SE:Standard Edition

Java EE:Enterprise Edition

Java ME:Micro Edition

这三者之间有啥关系呢?
Java学习记录1

简单来说,Java SE就是标准版,包含标准的JVM和标准库,而Java EE是企业版,它只是在Java SE的基础上加上了大量的API和库,以便方便开发Web应用、数据库、消息服务等,Java EE的应用使用的虚拟机和Java SE完全相同。

Java ME就和Java SE不同,它是一个针对嵌入式设备的“瘦身版”,Java SE的标准库无法在Java ME上使用,Java ME的虚拟机也是“瘦身版”。

毫无疑问,Java SE是整个Java平台的核心,而Java EE是进一步学习Web应用所必须的。我们熟悉的Spring等框架都是Java EE开源生态系统的一部分。不幸的是,Java ME从来没有真正流行起来,反而是Android开发成为了移动平台的标准之一,因此,没有特殊需求,不建议学习Java ME。

名词解释: 初学者学Java,经常听到JDK、JRE这些名词,它们到底是啥? JDK:Java Development Kit
JRE:Java Runtime Environment
简单地说,JRE就是运行Java字节码的虚拟机。但是,如果只有Java源码,要编译成Java字节码,就需要JDK,因为JDK除了包含JRE,还提供了编译器、调试器等开发工具。

关于JDK的安装,网上有很多的教程,除了JDK外,一个好的编写代码的软件也是需要安装的,比如Eclipse、IntelliJ Idea等,推荐使用Eclipse。

二、正式开始Java菜鸟学习之路

1.一个新语言,从输出Hello World!开始

先看一个例子,所有的语言都是从输出Hello World!开始的,这里也不例外,哈哈哈(精通各种Hello World!)

/**
 * 可以用来自动创建文档的注释
 */
public class Hello {
    public static void main(String[] args) {
        // 向屏幕输出文本:
        System.out.println("Hello, world!");
        /* 多行注释开始
        注释内容
        注释结束 */
    }
} // class定义结束

因为Java是面向对象的语言,一个程序的基本单位就是classclass是关键字,这里定义的class名字就是Hello

类名要求:

  • 类名必须以英文字母开头,后接字母,数字和下划线的组合
  • 习惯以大写字母开头

> 是不是看到Java的代码风格,跟其他的语言有很大的不同,有没有感觉有点不适呢?说真的,我学了几天的基本语法后,感觉Java还是挺不错的,哈哈哈,个人感觉!

另外这里大家应该看到了public这个关键字,后面还会看到private、protected等,从翻译就可以看出其大概意思。

另外一个很重要的是:目前,我们只需要知道,Java入口程序规定的方法必须是静态方法,方法名必须为main,括号内的参数必须是String数组。

2.Java的变量类型

Java中的变量类型包括基本类型和引用类型

基本数据类型
基本数据类型是CPU可以直接进行运算的类型。Java定义了以下几种基本数据类型:

  • 整数类型:byte,short,int,long
  • 浮点数类型:float,double
  • 字符类型:char
  • 布尔类型:boolean

不同的数据类型占用的字节数不一样。我们看一下Java基本数据类型占用的字节数:
┌───┐
byte
└───┘
┌───┬───┐
short
└───┴───┘
┌───┬───┬───┬───┐
int
└───┴───┴───┴───┘
┌───┬───┬───┬───┬───┬───┬───┬───┐
long
└───┴───┴───┴───┴───┴───┴───┴───┘
┌───┬───┬───┬───┐
float
└───┴───┴───┴───┘
┌───┬───┬───┬───┬───┬───┬───┬───┐
double
└───┴───┴───┴───┴───┴───┴───┴───┘
┌───┬───┐
char
└───┴───┘
byte恰好就是一个字节,而long和double需要8个字节。

Java中的整数运算和浮点数运算等于其他的语言类似,不做过多的论述。

3.字符和字符串

在Java中,字符和字符串是两个不同的类型。

字符是用char,字符串类型String是引用类型。
字符串连接
Java的编译器对字符串做了特殊照顾,可以使用**+**连接任意字符串和其他数据类型,这样极大地方便了字符串的处理。
不可变特性
Java的字符串除了是一个引用类型外,还有个重要特点,就是字符串不可变。

public class Main {
    public static void main(String[] args) {
        String s = "hello";
        System.out.println(s); // 显示 hello
        s = "world";
        System.out.println(s); // 显示 world
    }
}

虽然上面代码输出world,但其实内部是这样的一个过程:
观察执行结果,难道字符串s变了吗?其实变的不是字符串,而是变量s的“指向”。

执行String s = “hello”;时,JVM虚拟机先创建字符串"hello",然后,把字符串变量s指向它:

  s
  │
  ▼

┌───┬───────────┬───┐
│"hello"
└───┴───────────┴───┘
紧接着,执行s = “world”;时,JVM虚拟机先创建字符串"world",然后,把字符串变量s指向它:

  s ──────────────┐
                  │
                  ▼

┌───┬───────────┬───┬───────────┬───┐
│"hello" “world”
└───┴───────────┴───┴───────────┴───┘
原来的字符串"hello"还在,只是我们无法通过变量s访问它而已。因此,字符串的不可变是指字符串内容不可变。

理解了上面的过程,我们来看一个例子。`

public class Main {
    public static void main(String[] args) {
        String s = "hello";
        String t = s;
        s = "world";
        System.out.println(t); // t是"hello"还是"world"?
    }
}

输出的是hello还是world呢?显然是输出world!

4.数组类型

定义一个数组类型的变量,使用数组类型“类型[]”,例如,int[]。和单个基本类型变量不同,数组变量初始化必须使用new int[5]表示创建一个可容纳5个int元素的数组。

Java的数组有几个特点:

  • 数组所有元素初始化为默认值,整型都是0,浮点型是0.0,布尔型是false; 数组一旦创建后,大小就不可改变。
  • 要访问数组中的某一个元素,需要使用索引。数组索引从0开始,例如,5个元素的数组,索引范围是0~4。
  • 可以修改数组中的某一个元素,使用赋值语句,例如,ns[1] = 79;。
  • 可以用***数组变量.length***获取数组大小:

注意数组是引用类型,并且数组大小不可变。

我们观察下面的代码:

public class Main {
    public static void main(String[] args) {
        // 5位同学的成绩:
        int[] ns;
        ns = new int[] { 68, 79, 91, 85, 62 };
        System.out.println(ns.length); // 5
        ns = new int[] { 1, 2, 3 };
        System.out.println(ns.length); // 3
    }
}

数组大小变了吗?看上去好像是变了,但其实根本没变。

对于数组ns来说,执行ns = new int[] { 68, 79, 91, 85, 62 };时,它指向一个5个元素的数组:
Java学习记录1
执行ns = new int[] { 1, 2, 3 };时,它指向一个新的3个元素的数组:
Java学习记录1

但是,原有的5个元素的数组并没有改变,只是无法通过变量ns引用到它们而已。

字符串数组
如果数组元素不是基本类型,而是一个引用类型,那么,修改数组元素会有哪些不同?

字符串是引用类型,因此我们先定义一个字符串数组:
String[] names = {
“ABC”, “XYZ”, “zoo”
};
Java学习记录1
这里注意到原来names[1]指向的字符串"XYZ"并没有改变,仅仅是将names[1]的引用从指向"XYZ"改成了指向"cat",其结果是字符串"XYZ"再也无法通过names[1]访问到了。

public class Main {
    public static void main(String[] args) {
        String[] names = {"ABC", "XYZ", "zoo"};
        String s = names[1];
        names[1] = "cat";
        System.out.println(s); // s是"XYZ"还是"cat"?
    }
}

通过上面的讲解,显然输出的是XYZ!

5.输入与输出

输出

> 在前面的代码中,我们总是使用System.out.println()来向屏幕输出一些内容。 println是printline的缩写,表示输出并换行。因此,如果输出后不想换行,可以用print()

格式化输出使用System.out.printf(),通过使用占位符%?,printf()可以把后面的参数格式化成指定格式:

public class Main {
    public static void main(String[] args) {
        double d = 3.1415926;
        System.out.printf("%.2f\n", d); // 显示两位小数3.14
        System.out.printf("%.4f\n", d); // 显示4位小数3.1416
    }
}

占位符 说明
%d 格式化输出整数
%x 格式化输出十六进制整数
%f 格式化输出浮点数
%e 格式化输出科学计数法表示的浮点数
%s 格式化字符串

输入
和输出相比,Java的输入就要复杂得多。

我们先看一个从控制台读取一个字符串和一个整数的例子:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in); // 创建Scanner对象
        System.out.print("Input your name: "); // 打印提示
        String name = scanner.nextLine(); // 读取一行输入并获取字符串
        System.out.print("Input your age: "); // 打印提示
        int age = scanner.nextInt(); // 读取一行输入并获取整数
        System.out.printf("Hi, %s, you are %d\n", name, age); // 格式化输出
    }
}

Java学习记录1
练习
请帮小明同学设计一个程序,输入上次考试成绩(int)和本次考试成绩(int),然后输出成绩提高的百分比,保留两位小数位(例如,21.75%)。

import java.util.Scanner;
public class Main {    
public static void main(String[] args) 
{       
     System.out.print("请输入上次成绩:");        
     Scanner scanner=new Scanner(System.in);        
     int s=scanner.nextInt();        
     System.out.print("请输入此次成绩:");        
     int n= scanner.nextInt();        
     System.out.printf("成绩%s了%.2f%%",s>n?"下降":"提高",100*Math.abs(((1.0*n)/s)-1));    
     }
}

6.流程控制

这块主要是一些循环之类和判断之类的,比如:if&else,for&while&do
while,break&continue,switch等,主要说一下switch!

switch表达式
使用switch时,如果遗漏了break,就会造成严重的逻辑错误,而且不易在源代码中发现错误。从Java 12开始,switch语句升级为更简洁的表达式语法,使用类似模式匹配(Pattern Matching)的方法,保证只有一种路径会被执行,并且不需要break语句:

public class Main {
    public static void main(String[] args) {
        String fruit = "apple";
        switch (fruit) {
        case "apple" -> System.out.println("Selected apple");
        case "pear" -> System.out.println("Selected pear");
        case "mango" -> {
            System.out.println("Selected mango");
            System.out.println("Good choice!");
        }
        default -> System.out.println("No fruit selected");
        }
    }
}
输出:Selected apple

注意新语法使用**->**,如果有多条语句,需要用{}括起来。不要写break语句,因为新语法只会执行匹配的语句,没有穿透效应。

yield
大多数时候,在switch表达式内部,我们会返回简单的值。

但是,如果需要复杂的语句,我们也可以写很多语句,放到{…}里,然后,用yield返回一个值作为switch语句的返回值:

public class Main {
    public static void main(String[] args) {
        String fruit = "orange";
        int opt = switch (fruit) {
            case "apple" -> 1;
            case "pear", "mango" -> 2;
            default -> {
                int code = fruit.hashCode();
                yield code; // switch语句返回值
            }
        };
        System.out.println("opt = " + opt);
    }
}
输出:opt = -1008851410

三、结束

本次记录到此结束,下次再见! 记录时间:2020年11月1日,晚19:00