Java学习记录1
2020年10.25-10.31日
一、Java入门
为什么要学Java?因为Java是全球排名第一的编程语言,Java工程师也是市场需求最大的软件工程师,选择Java,就是选择了高薪。
为什么Java应用最广泛?
从互联网到企业平台,Java是应用最广泛的编程语言,原因在于:
为什么Java应用最广泛?
从互联网到企业平台,Java是应用最广泛的编程语言,原因在于:
- Java是基于JVM虚拟机的跨平台语言,一次编写,到处运行;
- Java程序易于编写,而且有内置垃圾收集,不必考虑内存管理;
- Java虚拟机拥有工业级的稳定性和高度优化的性能,且经过了长时期的考验;
- Java拥有最广泛的开源社区支持,各种高质量组件随时可用。
Java语言常年霸占着三大市场:
- 互联网和企业应用,这是Java EE的长期优势和市场地位;
- 大数据平台,主要有Hadoop、Spark、Flink等,他们都是Java或Scala(一种运行于JVM的编程语言)开发的;
- Android移动平台。
- 这意味着Java拥有最广泛的就业市场。
在这里说一句,我是学了一段时间的算法(ML和DL方向),看到实验室的师兄师姐今年找工作都是找的开发,算法都不太好找工作,过段转开发了。
随着Java的发展,SUN给Java又分出了三个不同版本:
Java SE:Standard Edition
Java EE:Enterprise Edition
Java ME:Micro Edition
这三者之间有啥关系呢?
简单来说,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是面向对象的语言,一个程序的基本单位就是class,class是关键字,这里定义的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个元素的数组:
执行ns = new int[] { 1, 2, 3 };时,它指向一个新的3个元素的数组:
但是,原有的5个元素的数组并没有改变,只是无法通过变量ns引用到它们而已。
字符串数组
如果数组元素不是基本类型,而是一个引用类型,那么,修改数组元素会有哪些不同?
字符串是引用类型,因此我们先定义一个字符串数组:
String[] names = {
“ABC”, “XYZ”, “zoo”
};
这里注意到原来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); // 格式化输出
}
}
练习
请帮小明同学设计一个程序,输入上次考试成绩(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
。
上一篇: Java学习记录1
下一篇: java小白学习记录8:循环2