前两天某公司的HR打电话来,问我JAVA的岗位是否愿意, 当时在地铁站里, 周围非常吵杂, 电话里重复两遍也没听清楚公司的名字, 然后HR把面试邀请发到我的email里. 当我看到这家居然就是心仪许久的公司的时候, 简直欣喜若狂, 就好像喜欢很久的女孩子突然和你说, 有空吗, 出来吃个饭吧.
从零开始学JAVA吧.
安装
用的Ubuntu, 直接apt-get
sudo apt install openjdk-11-jdk openjdk-11-jre
资料
我还是比较倾向从书籍开始, 书籍中的内容相对网络资源来说更加系统, 尤其是细节方面, 这将有助于后续对于该语言的理解和学习. 我选择 Core Java 这本书作为入门第一本书籍, 本文也将围绕这本书进行展开.
碎碎念
用惯了python,感觉JAVA哪里都不舒服, 类的声明一长串, 括号一大堆, 静态类型每次要声明而且不能变换类型, 输出一大长串贼麻烦... 第一次深切的感受到的那句 " 人生苦短, 我用 python "
搞吧, 麻烦就麻烦点了.
从hello world开始
淘气的作者说他就不用hello world!, 真可爱. 反正第一个程序是逃不开hello world了, 哈哈哈.
public class FirstSample {
public static void main(String[] args) {
System.out.println("We will not use 'Hello, World!'");
}
}
这里面的 println是带换行符的, print是不带换行符的. 可以自己在Jshell试试.
注释
和c/c++一样, //是行注释, /* */ 是块注释
数据类型
整型
JAVA数字类型需要注意的是: JAVA的数字大小范围不随机器和平台改变.
长整数后缀有个L(大写小写都行): 900000L
16进制数有前缀0x(大写小写都行): 0xABCD
8进制数有前缀0: 010 (不过比较容易混淆, 强烈建议不用8进制)
浮点型
image.png计算0/0的时候会产生一个NaN(Not a Number), 可以这样来判断:
if (Double.isNan(x))
不可以这样写:
if (x == Double.Nan) // 这个表达式永远为假
一个有趣的例子:
System.out.println(2.0-1.1)
// 0.8999999999999999
浮点小数很多时候并不准确, 如果想准确一点, 可以用 BigDecimal
char类型
char类型和c差不多, 有趣的时候, 在这里的char可以用unicode码, 更有趣的时候, unicode码在java程序里可以直接用, 并且会被翻译. 比如:
public static void main(String\u005B\u005D args)
这里的unicode的使用完全合法, java会把unicode自动翻译成对应的字符, 比如这里的\u005B\u005D 就分贝代表了 [ ] 所以完全没问题.
另外, java对于unicode的翻译优先级是比较高的. 高于字符串的翻译
boolean类型
两个值, 一个false一个true. 奇葩的是, 整型和布尔类型之间不可以转换!! 据说这种设计是为了避免 if(x=0) 这种低级错误. 比如x是布尔类型, 那么
if (x = 0)
这个语句在翻译的时候就会报错, 因为整型和布尔类型不能互相转换. (这牺牲可真是蛮大的, 用户体验一点都不好)
变量
变量用之前要声明, 和C/C++一样,声明以分号结束.这里的标识符有点特别,字母数字下划线不算完,还可以用unicode和符可以用, 也千万不要用.
在JAVA中, 定义和声明没区别
常量
使用final来定义常量, const是个没作用的保留关键词, (为了区分和C++的区别所以就是不用const吗?)
public static final double CM_PER_INCH = 2.54
数字类型之间的转换
image.png自动转换:
int n = 123456789;
float f = n; // f is 1.23456792E8
强转
double x = 9.997;
int nx = (int) x;
四舍五入的强转
double x = 9.997;
int nx = (int) Math.round(x);
String类型
String greeting = "Hello";
String s = greeting.substring(0, 3);
没有切片,没有下标.
可以直接和数字连接, 自动转换
String s = "abcdefg"
s + 1
// "abcdefg1"
join方法
String all = String.join(" / ", "S", "M", "L", "XL");
// all is the string "S / M / L / XL"
字符串相等判断
"Hello".equalsIgnoreCase("hello") // true
"Hello".equals("Hello") //false
不要用==来判断字符串是否相等, JAVA的字符串是不可变类型, 都存储在堆中, ==只能判断两个字符串是否存储在同一个位置. 所以一定记得要用equals来判断字符串是否相等.
字符串判空
if (str.length() == 0)
if (str.equals(""))
两种都可以
有时候 String类型可能是null, 所以检测就变成了:
if (str != null && str.length() != 0)
获取某个字符
char first = greeting.charAt(0); // first is 'H' char last = greeting.charAt(4); // last is 'o'
具体关于String查看JAVA 11 API
输入输出
输入
输入要先构造扫描器
在这之前要先引用, 因为扫描器在这个包里面
import java.util.*;
然后构造扫描器
Scanner in = new Scanner(System.in);
System.out.print("What is your name? ");
String name = in.nextLine(); // 读取一行
String firstName = in.next(); // 读取一个单词 (空格结束)
读取整型
System.out.print("How old are you? ");
int age = in.nextInt();
读取密码:
Console cons = System.console();
String username = cons.readLine("User name: ");
char[] passwd = cons.readPassword("Password: ");
出于安全考虑密码返回的是一个char型的数组
格式化输出
double x = 10000.0 / 3.0;
System.out.print(x);
//3333.3333333333335
System.out.printf("%8.2f", x);
//3333.33
基本格式和C语言的printf大体相同. 不同的是有一些Flags, 如下:
image.png image.png image.png文件读写
读
Scanner in = new Scanner(Paths.get("myfile.txt"), "UTF-8");
注意如果文件路径中有反斜杠, 要转义.
写
PrintWriter out = new PrintWriter("myfile.txt", "UTF-8");
读写异常
public static void main(String[] args) throws IOException {
Scanner in = new Scanner(Paths.get("myfile.txt"), "UTF-8"); . . .
}
控制流
条件
if 语句
if (yourSales >= target) {
performance = "Satisfactory"; bonus = 100;
}
if-else语句
if (yourSales >= target) {
performance = "Satisfactory";
bonus = 100 + 0.01 * (yourSales - target);
}else {
performance = "Unsatisfactory"; bonus = 0;
}
可以连续if-else
if (condition){
statement;
}else if (condition){
statement;
}else{
statement;
}
循环
//while
while(condition){
statement;
}
// do-while
do{
statement;
}while(condition)
// for 循环
for (int i = 1; i <= 10; i++)
System.out.println(i);
关于 break
JAVA的break大体和c/c++相同, 有一些特别的就是, 它结合了goto的特性, 你可以直接跳出多层循环.但是不同的是break的这个特性只能往外跳, 不能往里跳. 而且是跳到标签的同一级代码块
read_data:
while (. . .) // this loop statement is tagged with the label
{
. . .
for (. . .) // this inner loop is not labeled
{
System.out.print("Enter a number >= 0: ");
n = in.nextInt();
if (n < 0) // should never happen—can't go on
break read_data; // break out of read_data loop . . .
}
}
// this statement is executed immediately after the labeled break
if (n < 0) // check for bad situation
{
statement; // deal with bad situation
}
else {
statement; // carry out normal processing
}
continue和C/C++一样, 不必重复
大数字运算
BigInteger可以实现任意精度的数字计算.
// 用valueof把普通的整数转换成大整数类型
BigInteger a = BigInteger.valueOf(100);
JAVA没有运算符重载, 所以要调用方法才能进行运算
BigInteger a = BigInteger.valueOf(1000000);
BigInteger b = BigInteger.valueOf(9999999);
a.add(b); // 10999999
a.multiply(b); // 9999999000000
- BigInteger add(BigInteger other)
- BigInteger subtract(BigInteger other)
- BigInteger multiply(BigInteger other)
- BigInteger divide(BigInteger other)
-
BigInteger mod(BigInteger other)
returns the sum, difference, product, quotient, and remainder of this big integer and other. -
int compareTo(BigInteger other)
returns 0 if this big integer equals other, a negative result if this big integer is less than other, and a positive result otherwise. -
static BigInteger valueOf(long x)
returns a big integer whose value equals x.
数组
定义
int[] a;
//这样也可以
int a[];
这个才是真正的创建
int[] a = new int[100];
整型数组默认为全0
浮点数为全0.0
String数组默认为全null
遍历
for (int i = 0; i < a.length; i++)
System.out.println(a[i]);
另一种有趣的输出方式
System.out.println(Arrays.toString(a));
//[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
for-each 循环
比如数组:
for (int element : a)
System.out.println(element);
数组初始化
int[] smallPrimes = { 2, 3, 5, 7, 11, 13 };
数组复制
你可以复制数组, 不过复制之后, 两个数组指向同一个对象. 但是一改全动.
int[] luckyNumbers = smallPrimes;
luckyNumbers[5] = 12; // now smallPrimes[5] is also 12
命令行参数
public class Message {
public static void main(String[] args) {
if (args.length == 0 || args[0].equals("-h"))
System.out.print("Hello,");
else if (args[0].equals("-g"))
System.out.print("Goodbye,");
// print the other command-line arguments
for (int i = 1; i < args.length; i++)
System.out.print(" " + args[i]);
System.out.println("!");
}
}
然后命令行调用
java Message -g cruel world
数组就是这样
args[0]: "-g"
args[1]: "cruel"
args[2]: "world"
输出
Goodbye, cruel world!
注意和c语言不同, java的args数组中不存储程序名.
网友评论