Java作业-9
JavaFX,文本处理
Comparable接口与Comparator接口之间有什么不同指出?他们分别属于哪一个包?
| 特征/接口 | Comparable | Comparator |
|---|---|---|
| 定义 | 用于定义对象的自然排序顺序。实现此接口的类可以自动排序。 | 用于定义两个对象间的比较规则。允许为类定义多种排序规则。 |
| 方法 | 只有一个方法:compareTo(T o)。 |
主要方法:compare(T o1, T o2)。还有其他辅助方法,如reversed()、thenComparing()等。 |
| 使用场景 | 类有明确的“自然”排序顺序时使用,如数字、字母顺序。 | 为某个类定义不同的排序规则,或该类没有自然排序且不希望或无法修改原始类。 |
| 所在包 | java.lang |
java.util |
如何创建一个整数优先队列?默认情况下,元素如何以优先队列排序?在优先队列中,拥有最小数值的元素会被赋予最高优先级吗?
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
如果元素类实现了Comparable接口,队列就会根据compareTo方法定义的自然顺序对元素进行排序。
最小数值的元素会被赋予最高优先级
如何创建一个将元素的自然顺序颠倒的优先队列?
在构造函数中传递一个自定义的Comparator对象
public class ReverseOrderPriorityQueue {
public static void main(String[] args) {
// 创建一个Comparator,颠倒自然顺序
Comparator<Integer> reverseOrder = (o1, o2) -> o2.compareTo(o1);
// 使用自定义Comparator创建PriorityQueue
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(reverseOrder);
// 添加一些元素进行测试
priorityQueue.add(10);
priorityQueue.add(20);
priorityQueue.add(5);
priorityQueue.add(1);
// 循环并删除队列中的每个元素
while (!priorityQueue.isEmpty()) {
System.out.println(priorityQueue.remove());
}
}
}
HashSet、LinkHashSet和TreeSet之间的区别是什么?
| 特性 | HashSet | LinkedHashSet | TreeSet |
|---|---|---|---|
| 内部数据结构 | 基于哈希表(HashMap实例) | 基于哈希表和双向链表 | 基于红黑树(自平衡的二叉搜索树) |
| 顺序性 | 无序 | 维护插入顺序 | 按自然排序或指定的Comparator排序 |
| 性能 | 增删查操作通常是 O(1) | 增删查操作通常是 O(1),但略慢于HashSet | 增删查操作大约是 O(log n) |
| 使用场景 | 不需要维护元素顺序的快速查找、插入和删除 | 需要维护元素插入顺序的快速查找、插入和删除 | 需要按顺序存储元素的情况 |
| 所在包 | java.util.HashSet | java.util.LinkedHashSet | java.util.TreeSet |
替换,输出是?
A sorted set of geometric objects
area = 20.0
area = 4.0
area = 5021.538
合适的数据结构
21.10 Set或HashSet
21.11 LinkedHashSet
21.12 TreeSet
21.13 普通数组 a[10]
21.14 ArrayList
21.15 LinkedList
修改程序清单20-6,使得一个球在被创建的时候赋给一个2~20的随机半径。当单击“-”按钮时,最大的一个球被移除
package com.example;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollBar;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class BallRemover extends Application {
@Override
public void start(Stage primaryStage) {
// 创建包含多个球的面板
MultipleBallPane ballPane = new MultipleBallPane();
ballPane.setStyle("-fx-border-color: #abcdef");
// 创建添加和减少球体的按钮
Button btAdd = new Button("+");
Button btSubtract = new Button("-");
HBox hBox = new HBox(10);
hBox.getChildren().addAll(btAdd, btSubtract);
hBox.setAlignment(Pos.CENTER);
// 设置按钮的事件处理
btAdd.setOnAction(e -> ballPane.add());
btSubtract.setOnAction(e -> ballPane.subtract());
// 暂停和恢复动画的事件处理
ballPane.setOnMousePressed(e -> ballPane.pause());
ballPane.setOnMouseReleased(e -> ballPane.play());
// 创建并设置滚动条以控制动画速度
ScrollBar sbSpeed = new ScrollBar();
sbSpeed.setMax(20);
sbSpeed.setValue(10);
ballPane.rateProperty().bind(sbSpeed.valueProperty());
// 设置面板布局
BorderPane pane = new BorderPane();
pane.setCenter(ballPane);
pane.setTop(sbSpeed);
pane.setBottom(hBox);
// 创建和设置场景
Scene scene = new Scene(pane, 250, 150);
primaryStage.setTitle("BallRemover");
primaryStage.setScene(scene);
primaryStage.show();
}
private class MultipleBallPane extends Pane {
private Timeline animation;
public MultipleBallPane() {
// 初始化动画
animation = new Timeline(
new KeyFrame(Duration.millis(50), e -> moveBall()));
animation.setCycleCount(Timeline.INDEFINITE);
animation.play(); // 启动动画
}
public void add() {
// 随机创建一个新球并添加到面板中
Color color = new Color(Math.random(), Math.random(), Math.random(), 0.5);
getChildren().add(new Ball(30, 30, Math.random() * 16 + 5, color));
}
public void subtract() {
if (getChildren().size() > 0) {
// 移除最大的球
Ball largestBall = (Ball) (getChildren().get(0));
for (Node node : getChildren()) {
Ball ball = (Ball) node;
if (ball.getRadius() > largestBall.getRadius()) {
largestBall = ball;
}
}
getChildren().remove(largestBall);
}
}
// 控制动画的播放和暂停
public void play() {
animation.play();
}
public void pause() {
animation.pause();
}
// 获取动画速度的属性
public DoubleProperty rateProperty() {
return animation.rateProperty();
}
// 移动场景中的所有球
protected void moveBall() {
for (Node node : this.getChildren()) {
Ball ball = (Ball) node;
// 检查球是否触碰到边界
if (ball.getCenterX() < ball.getRadius() || ball.getCenterX() > getWidth() - ball.getRadius()) {
ball.dx *= -1;
}
if (ball.getCenterY() < ball.getRadius() || ball.getCenterY() > getHeight() - ball.getRadius()) {
ball.dy *= -1;
}
// 更新球的位置
ball.setCenterX(ball.dx + ball.getCenterX());
ball.setCenterY(ball.dy + ball.getCenterY());
}
}
}
class Ball extends Circle implements Comparable<Ball> {
private double dx = 1, dy = 1;
Ball(double x, double y, double radius, Color color) {
super(x, y, radius);
setFill(color);
}
// 实现比较接口用于排序
@Override
public int compareTo(Ball b) {
return Double.compare(this.getRadius(), b.getRadius());
}
}
}
从文本文件中读取单词,并将所有不重复的单词按照升序显示,文本文件作为命令行参数传递
import java.io.File;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
public class Test2102 {
public static void main(String[] args) throws Exception {
// 检查命令行参数
if (args.length != 1) {
System.out.println("Usage: java Test2102 filename");
System.exit(1);
}
File file = new File(args[0]); // 从命令行参数获取文件名
Set<String> treeSet = new TreeSet<>();
if (file.exists()) {
try (Scanner input = new Scanner(file)) {
while (input.hasNextLine()) {
String line = input.nextLine().trim();
// 使用正则表达式分割字符串
String[] tokens = line.split("\\s+|\\.|,|\\(|\\)|\"|'|;|-");
for (String token : tokens) {
if (!token.isEmpty()) { // 检查分割出的字符串是否为空
treeSet.add(token);
}
}
}
} catch (Exception ex) {
System.err.println("Error reading file: " + ex.getMessage());
}
} else {
System.out.println("File " + args[0] + " does not exist");
}
// 输出不重复的单词
System.out.println(treeSet);
}
}
将一个Java文件转换成一个HTML文件,在HTML中,关键词、注释和字面量分别用粗体的深蓝色、绿色和蓝色显示。使用命令行传递Java文件和HTML文件
import java.util.*;
import java.io.*;
public class Test2105 {
// Java关键词列表
static String[] keywordString = {
"abstract", "assert", "boolean",
"break", "byte", "case", "catch", "char", "class", "const",
"continue", "default", "do", "double", "else", "enum",
"extends", "for", "final", "finally", "float", "goto", "if",
"implements", "import", "instanceof", "int", "interface",
"long", "native", "new", "package", "private", "protected",
"public", "return", "short", "static", "strictfp", "super",
"switch", "synchronized", "this", "throw", "throws",
"transient", "try", "void", "volatile", "while",
"true", "false", "null" };
public static void main(String[] args) {
// 检查命令行参数
if (args.length != 2) {
System.out.println("Usage: java Test2105 sourceFile targetFile");
System.exit(1);
}
File sourceFile = new File(args[0]);
File targetFile = new File(args[1]);
if (!sourceFile.exists()) {
System.out.println("Source file " + args[0] + " does not exist");
System.exit(2);
}
Set<String> keywordSet = new HashSet<>(Arrays.asList(keywordString));
// 读取源文件并转换为HTML格式
try (Scanner input = new Scanner(sourceFile);
PrintWriter output = new PrintWriter(targetFile)) {
StringBuffer sb = new StringBuffer("<html><body>");
while (input.hasNext()) {
String line = input.nextLine();
// 处理每一行的内容
String htmlLine = processLine(line, keywordSet);
sb.append(htmlLine);
}
sb.append("</body></html>");
output.println(sb.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
// 处理一行文本,转换为HTML格式
private static String processLine(String line, Set<String> keywordSet) {
// 使用StringBuilder而不是StringBuffer,因为它在单线程中效率更高
StringBuilder htmlLine = new StringBuilder();
// 检查是否为单行注释
if (line.trim().startsWith("//")) {
return "<p style=\"color:green\">" + line + "</p>";
}
// 分割字符串以处理可能的注释和字面量
String[] tokens = line.split("\"");
// 处理每个分割出的部分
boolean isLiteral = false; // 标记是否处于字符串字面量中
for (String token : tokens) {
if (isLiteral) {
// 字符串字面量用蓝色显示
htmlLine.append("<font color=blue>\"").append(token).append("\"</font>");
isLiteral = false;
} else {
// 分割非字面量部分以进一步处理关键词和注释
String[] words = token.split("[\\s+()]");
for (String word : words) {
if (keywordSet.contains(word)) {
// 关键词用粗体深蓝色显示
htmlLine.append("<font color=darkblue><b>").append(word).append("</b></font>");
} else if (word.startsWith("//")) {
// 单行注释用绿色显示
htmlLine.append("<font color=green>").append(word);
// 注释之后的内容全部视为注释
htmlLine.append(token.substring(word.length())).append("</font>");
break;
} else {
htmlLine.append(word);
}
htmlLine.append(" ");
}
isLiteral = true;
}
}
// 每一行结束后添加换行标记
htmlLine.append("<br>");
return htmlLine.toString();
}
}