本节目标:
- 熟悉IntelliJ的使用,并用IntelliJ完成本次lab的编程任务
- 熟悉for循环、switch语句
- 初探文件输入,提高字符串处理能力
- 维护世界的爱与和平
IntelliJ IDEA被认为是当前Java开发效率最快的IDE工具。它是一种商业化销售的Java集成开发环境(Integrated Development Environment,IDE)工具软件,由捷克软件公司JetBrains在2001年1月时推出最初版。
在lab0中,我们曾简单提到过IntelliJ。IntelliJ在一些大型项目中的高效使得它备受各大公司的青睐,我们也将用它来开发我们的期中project斗兽棋。
为了让大家尽快上手,机智善良的@lfs TA已经为大家录制了十分详细的Intellij入门视频,相信大家已经逐步感受到了IDE的便利。这次lab我们就需要在IntelliJ进行编程,并运行我们自己程序。
开始编程之前,我们先新建一个专属这次lab的project吧✌️
-
新建project
可以在welcome界面单击
Create New Project
,如图或者,在菜单栏中依次单击
File
->New
->Project...
,如图 -
弹出新建项目的窗口后,在最左一列选择Java,其它设置不用改,单击右下角的
Next
-
跳到下一界面后,这里可以什么都不选;
如果勾选
Create project from template
,并选择Java Hello World
,则最终新建的项目中,在src
文件夹中会自动生成一个输出"Hello World"的java文件 -
接下来是输入项目名及路径。在
Project name
中填写你想要的项目名称,如Lab4
,下方的Project location
中也会自动更改路径名(Project location
其实不一定用自动生成的路径,可以单击右方的...
进行选择) -
单击右下角的Finish,则完成了新项目的建立。
-
在当前窗口中,布局大致如下图,左边一栏是整个项目的层次结构,方便你查看需要的文件,右边则是打开的文件的详情。
Main.java
在src
目录下,是自动生成的。 -
运行这个project,可以直接单击右上角中的绿色三角形符号,或者也可以从菜单栏中依次单击
Run
->Run...
在今后的学习中,你的项目会越来越复杂,会有很多个java文件互相配合,那么哪个文件是你整个项目的入口呢?或者说,你想要直接运行哪个java程序呢?之前在
atom
里,我们运行的是当前窗口打开的这个文件,在IntelliJ中呢?事实上,在java项目中,IntelliJ会自动找到所有定义了
public static void
的main
方法的public class
,如Step 6中自动生成的Main.java
中的public class Main
。如果你的项目中恰好有多个这样的public class
,很可能就会列出所有这些类,并让你选择运行哪一个。像Step 7中图这样,是默认运行Main
这个类;同样的,如果你有多个符合条件可运行的类,单击图中向下的三角形,你可以选择你想运行的类。所以你在这个project中最直接调用的java文件不一定要叫
Main
(比如project自动生成的这个),只要你想调用的文件中有public static void
的main
方法就好了。当然,还有一种运行指定的文件的方法,就是在左边的文件浏览一栏中,选中你想运行的文件,右键并选择
Run
。
通过文件输入一个有意义的数字字符串,你需要将这条字符串“翻译”成字符画~
number | output |
---|---|
0 | ' '(空格) |
1 | 'X' |
2 | '.' |
3 | '\n'(即换行) |
在本次lab的同级目录下有待翻译的字符串文件data.txt
,请把它放置在和src
目录同级的路径下。之前的课上我们学过可以用Scanner(System.in)
读取终端中传入的参数,而如果我们把System.in
换成一个文件,则可以输入文件中的内容了。
我们可以用下面这段代码来读取文件data.txt
中的内容
File file = new File("data.txt");
Scanner input = new Scanner(file);
String dataString = input.next();
在这段代码中,File
和Scanner
都是java中已经定义好的一些工具类,需要显性地引用一下,你当然可以直接在文件最开始手动地输入
import java.io.File;
import java.util.Scanner;
但是在IntelliJ中,当你输入File
或者Scanner
这些关键字的时候,编译器会自动跳出你可以选择引用的工具类名称,你只需要选中想要的选择,这些工具类就会自动出现在文件最开始了😉
这看上去已经成功读入了文件内容了对不对?但如果你直接运行这段代码,应该会得到一段程序报错:
java: unreported exception java.io.FileNotFoundException; must be caught or declared to be thrown
从字面意思上看来,就是你没有处理可能会出现的FileNotFoundException
,这是一种常见的无法找到文件的异常情况。而什么是异常,这个具体会在今后学习异常
的章节中详细说明。而在这次lab中,你只需要知道,当你要从文件中读入内容时,有很大的可能你希望读取的文件不存在(这些可能呢,比如手残打错文件名了,比如你的文件放错地方了,或者真的不存在这个文件),而为了各种目的(比如这个名字的文件不存在其实没关系,还有别的默认内容可以读取;或者后面的代码其实更重要,我不希望这个文件错误搞崩之后的代码运行),我们需要对这种文件不存在的情况进行处理,并且最好留下log报告给开发者。
再次感谢智能的IntelliJ🙏它给出了解决这种异常的可能的方案,我们这次lab用这种自动给出的处理方案就足够了。如图,当鼠标点击到可能出错的这句话上时,这句话开头会出现一个红色的灯泡💡,表明有改进方案。
而我们单击这个红色灯泡,选择Surround with try/catch
,就有自动的解决方案。
try {
input = new Scanner(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
这样,这段读取文件内容的代码就不会报错了。新的代码的意思是,编译器先尝试(try)运行一下可能出错的代码段,如果捕捉(catch)到了FileNotFound
这个异常,就输出导致这个异常的一系列代码调用路径。
接下来我们需要对输入的信息进行处理,完全就是字符串处理的工作了。因为将密文字符串“翻译”成字符画,是字符与字符的对应,所以我们要获取单个字符。这时我们需要用到charAt
函数,使用方法同上次lab中出现的substring
类似,如下代码即可获得dataString
第i
位的字符了。
char theChar = dataString.charAt(i);
而我们需要处理整个字符串,就需要遍历字符串的所有字符,这个可以用for循环来实现。循环中需要处理的字符个数当然就是整个字符串的长度啦,对于一个字符串str
,我们可以用str.length()
获取这个字符串的长度。
对照问题描述中的翻译表,我们可以得到一些一一对应关系,请用switch
语句实现。比如
switch (theChar) {
case '0':
System.out.print(' ');
break;
default:
System.out.println();
}
我们这次lab需要读取的文件内容只有一行,所以用
String dataString = input.next();
完全足够。而大多数情况下,文件中绝不只有一行内容需要输入,在不知道具体会有多少行输入的情况下,请思考一下需要怎么改这段代码。
Hint:
input.hasNext()会返回一个boolean值。当文件未结束时返回true,否则返回false。
在期中project斗兽棋中,我们需要读入初始的游戏地图,也是类似的多行输入。而地图中出现的元素较多,有0-8总共9种情况。如果用if或者switch语句进行一一对应肯定可以实现。但这样代码量较多,而且这些对应关系不仅仅在地图的输出中会被用到,其它代码逻辑中也可能被用到。如果每次都用条件判断,会过于重复。那么应该如何对应呢?
*希望大家自学数组的部分内容,尝试用数组而不是条件判断语句完成lab3和lab4☘️