Java 类、集合、文件练习

OOP h19

q01

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.huawei.classroom.student.h19.q01;

/**
* @author super
*/
public class Dog {
private String speakStr;

public Dog() {
speakStr = "wangwang";
}

public String speak() {
return this.speakStr;
}
}

q02

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.huawei.classroom.student.h19.q02;

/**
* @author super
*/
public class Person {
private String name;

public Person(String n) {
this.name = n;
}

public String getName() {
return this.name;
}
}
1
2
3
4
5
6
7
8
9
10
package com.huawei.classroom.student.h19.q02;

/**
* @author super
*/
public class Student extends Person{
public Student(String n) {
super(n);
}
}

q03

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.huawei.classroom.student.h19.q03;

/**
* @author super
*/
public class ArrayUtil {
public ArrayUtil() {
}

public int getMin(int[] array) {
int min = array[0];
for (int arrayEle : array) {
min = Math.min(min, arrayEle);
}
return min;
}
}

q04

去掉重复字符。

第一次出现的字符建立一个集合,只需要依次判断字符串中的字符:若在此集合中,则跳过;否则加入此集合。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.huawei.classroom.student.h19.q04;

/**
* @author super
*/
public class StrUtil {
public StrUtil() {

}

public String removeDulpicatedChar(String str) {
int i;
StringBuilder result = new StringBuilder();
for (i = 0; i < str.length(); i++) {
char curChar = str.charAt(i);
if (!isInSet(curChar, set)) {
result.append(curChar);
}
}
return result.toString();
}
public boolean isInSet(char cha, StringBuilder set) {
int i;
for (i = 0; i < set.length(); i++) {
if (cha == set.charAt(i)) {
return true;
}
}
return false;
}
}

q05

完成 StudentUtil,使其具有如下功能:

  • 一个文本文件中 学生姓名,科目,单科成绩;(见 score.txt,这个文件肯定是UTF-8 编码)

  • 将所有学生按总成绩从高到低排名,如果成绩并列则按语文从高到低排列,如果语文成绩也相同,则按数学由高到低排列,如果数学成绩也相同,则按英语由高到低排列(不会出现总分相同&&语文相同&&数学相同&&英语相同情况)

首先应读取文件,其次按格式存储文件中的数据,然后对数据进行排序。

0x00 读取文件 readLines

Test 没有捕捉异常,所以此处不能抛出异常,应捕捉。

FileReader 读文件,LineNumberReader 读行。读取的同时去掉了末尾的分号,且用逗号分割后存放到一个字符串数组。

最终返回一个字符串数组的列表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public List<String[]> readLines(String filename) {
String line = "";
Reader reader = null;
List<String[]> result = new ArrayList<>();
try {
reader = new FileReader(filename);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (reader == null) {
return null;
}
LineNumberReader lineReader = new LineNumberReader(reader);

try {
while (true) {
line = lineReader.readLine();
if (line == null) {
break;
}
result.add(line.replace(";", "").split(","));
}
} catch (IOException e) {
e.printStackTrace();
}
return result;
}

0x01 格式化每行数据 Score

上面用字符串数组存放一行数据,但最终需要排序,显然字符串数组不利于排序。

可以把学生的成绩抽象为一个 Score 类。注意不是把一行数据抽象为一个类,因为很有可能存在许多行对应同一个学生的情况。

根据要求,排序的依据依次是总成绩、语文成绩、数学成绩、英语成绩,其他成绩都不重要。所以这个类的成员变量应该包括姓名、总成绩、语文成绩、数学成绩和英语成绩。

Score 类的初始化即给这五个变量赋值。为了便于排序,需要实现 Comparable 接口,重写 compareTo 方法,内容就是排序的规则。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.huawei.classroom.student.h19.q05;


/**
* @author super
*/
public class Score implements Comparable<Object> {
private final String name;
private final int totalScore;
private final int chineseScore;
private final int mathScore;
private final int englishScore;

public Score(String name, int chineseScore, int mathScore, int englishScore, int totalScore) {
this.name = name;
this.chineseScore = chineseScore;
this.mathScore = mathScore;
this.englishScore = englishScore;
this.totalScore = totalScore;
}
@Override
public int compareTo(Object o) {
if (!(o instanceof Score)) {
return -1;
}
if (this.totalScore > ((Score) o).totalScore) {
return 1;
} else if (this.totalScore < ((Score) o).totalScore) {
return -1;
} else if (this.chineseScore > ((Score) o).chineseScore) {
return 1;
} else if (this.chineseScore < ((Score) o).chineseScore) {
return -1;
} else if (this.mathScore > ((Score) o).mathScore) {
return 1;
} else if (this.mathScore < ((Score) o).mathScore) {
return -1;
} else {
return Integer.compare(this.englishScore, ((Score) o).englishScore);
}
}
public String getName() {
return name;
}
}

0x02 比较器 ScoreComparator

实现 Comparator 接口,重写 compare 方法。

为增强可扩展性,定义了排序方式(升序/降序)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.huawei.classroom.student.h19.q05;

import java.util.Comparator;

/**
* @author super
*/
public class ScoreComparator implements Comparator<Score> {
/**
* 1 asc
* -1 des
*/
private final int order;
public ScoreComparator(int order) {
super();
this.order = order;
}
@Override
public int compare(Score s1, Score s2) {
int result = s1.compareTo(s2);
if (this.order == 1) {
return result;
} else {
return -result;
}
}
}

0x03 格式转换 initScoreLists

上面获取了文本的一行为字符串数组,需要先转换为列表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* @param scoreLine 一行文本
* @return 0 姓名 1 语文 2 数学 3 英语 4 当前成绩
*/
public void line2list(String[] scoreLine, List<String> scoreList) {
String name = scoreLine[0];
String object = scoreLine[1];
String score = scoreLine[2];
scoreList.set(0, name);
scoreList.set(4, score);
switch (object) {
case "语文":
scoreList.set(1, score);
break;
case "数学":
scoreList.set(2, score);
break;
case "英语":
scoreList.set(3, score);
break;
default:
}
}

在初始化 Score 类型列表时,重复遍历以找到当前学生的所有科目的成绩,并存放到对应位置、计算总成绩:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public List<Score> initScoreLists(String filename) {
int i, j;
List<String[]> scores = readLines(filename);
Set<String> nameSet = new HashSet<>();
List<Score> scoreList = new ArrayList<>();
for (i = 0; i < scores.size(); i++) {
String name = "";
int totalScore = 0, chineseScore = 0, mathScore = 0, englishScore = 0;
List<String> scoreLine = new ArrayList<>(Arrays.asList("", "0", "0", "0", "0"));
line2list(scores.get(i), scoreLine);
name = scoreLine.get(0);
if (nameSet.contains(name)) {
continue;
} else {
nameSet.add(name);
}
totalScore += Integer.parseInt(scoreLine.get(4));
for (j = i + 1; j < scores.size(); j++) {
if (scores.get(j)[0].equals(name)) {
line2list(scores.get(j), scoreLine);
totalScore += Integer.parseInt(scoreLine.get(4));
}
}

chineseScore = Integer.parseInt(scoreLine.get(1));
mathScore = Integer.parseInt(scoreLine.get(2));
englishScore = Integer.parseInt(scoreLine.get(3));
Score score = new Score(name, chineseScore, mathScore, englishScore, totalScore);
scoreList.add(score);
}
return scoreList;
}

0x04 排序 sort

降序。

1
2
3
4
5
6
7
8
9
10
public List<String> sort(String filename){
int i;
List<String> result = new ArrayList<>();
List<Score> scoreLists = initScoreLists(filename);
scoreLists.sort(new ScoreComparator(-1));
for (i = 0; i < scoreLists.size(); i++) {
result.add(scoreLists.get(i).getName());
}
return result;
}