首页
留言
关于
统计
友情链接
Search
1
java面试题05
261 阅读
2
java魔方矩阵
109 阅读
3
Java中的包
98 阅读
4
java中接口的作用
95 阅读
5
java中this关键字
68 阅读
随笔
笔记
计算机基础
JAVA
web前端
分享
经验
软件
其他
登录
/
注册
Search
标签搜索
JAVA
笔记
面试
五子棋
游戏
阿涛
累计撰写
23
篇文章
累计收到
9
条评论
首页
栏目
随笔
笔记
计算机基础
JAVA
web前端
分享
经验
软件
其他
页面
留言
关于
统计
友情链接
搜索到
23
篇与
ATAO
的结果
2022-07-21
java面试题01
1.ArrayList和LinkedList的区别底层数据结构不同ArrayList是基于数组的LinkedList是基于双向链表的效率不同数组元素在内存中是连续存放的,所以ArrayList查询效率高,插入删除效率低链表元素在内存中存放的特点是不连续的,所以LinkedList插入删除效率高,查询效率低2.HashMap和HashTable的区别相同点:HashMap和HashTable都实现了Map、Cloneable(可克隆)、Serializable(可序列化)三个接口不同点:底层数据结构不同,jdk1.7底层都是数组+链表,jdk1.8 HashMap加入了红黑树Hashtable不允许键值为null,HashMap允许键值为nullHashtable继承的是Dictionary类,而HashMap继承的是AbstractMap类同步性不同,Hashtable是同步的(synchronized),HashMap不是同步的,因此Hashtable是线程安全的,HashMap是线程不安全的添加键值对时采用的hash值算法不同,HashMap采用自定义的hash算法,Hashtable直接采用hashCode()初始容量不同,HashMap初始容量为16,Hashtable初始容量为11,两者的负载因子都是0.75扩容机制不同,当已用容量>总容量*负载因子时,HashMap扩容规则为当前容量翻倍,Hashtable扩容规则为当前容量翻倍+1支持遍历种类不同迭代器不同部分API不同3.sleep和wait的区别sleep()是线程类Thread的静态方法,wait是属于Object的成员方法sleep只释放CPU没有释放锁,wait释放了锁wait只能通过notify或notifyAll来唤醒sleep可以在任何地方使用,wait只能在同步控制方法或同步控制块中使用4.接口和抽象类的区别构造方法:抽象类有构造方法,用于子类实例化使用。接口没有构造方法。成员变量:抽象类的成员变量可以是变量也可以是常量。接口的成员变量只能是常量,默认修饰符public static final成员方法:抽象类的成员方法可以是抽象的也可以是非抽象的,接口在1.7中方法只能是抽象的,1.8后可以写default和static方法5.final、finalize和finally的区别final修饰变量,变量在初始化以后不能被修改final修饰方法,方法不能被子类重写final修饰类,类不能被继承finalize方法:当一个对象是不可达对象的时候,GC会在某一个不确定的时候回收该对象,在回收该对象之前,JVM会调用该对象finalize方法以释放该对象占用的其他资源,不建议使用finalize方法,因为finalize的执行时机是不确定的finally用在try-catch或try块之后,无论try或catch中是否有异常,其中的代码一定会执行。如果try或catch中有return语句,则finally会先执行然后再return
2022年07月21日
19 阅读
0 评论
0 点赞
2022-04-04
javafx实现五子棋游戏
设计一个五子棋游戏,实现悔棋、保存棋谱、棋谱复盘等功能。窗口程序依赖于javafx,编译运行请使用jdk1.8。完成结果如下图:完整代码:棋子类 import javafx.scene.paint.Color; /** * 棋子描述类 */ public class Chess { /** * 棋子横坐标 */ private final int x; /** * 棋子纵坐标 */ private final int y; /** * 棋子颜色 */ private final Color color; public Chess(int x, int y, Color color) { this.x = x; this.y = y; this.color = color; } public int getX() { return x; } public int getY() { return y; } public Color getColor() { return color; } @Override public String toString() { return "Chess [x=" + x + ", y=" + y + ", color=" + color + "]"; } }主框架类import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.Alert; import javafx.scene.control.Alert.AlertType; import javafx.scene.control.Button; import javafx.scene.control.ButtonType; import javafx.scene.layout.Background; import javafx.scene.layout.BackgroundFill; import javafx.scene.layout.Pane; import javafx.scene.paint.Color; import javafx.scene.shape.Circle; import javafx.scene.shape.Line; import javafx.stage.FileChooser; import javafx.stage.FileChooser.ExtensionFilter; import javafx.stage.Stage; import java.io.*; import java.util.ArrayList; import java.util.Optional; import java.util.function.Predicate; /** * 主框架类 */ public class MyChessApp extends Application { /** * 棋盘宽度 */ private static final int WIDTH = 600; /** * 棋盘高度 */ private static final int HEIGHT = 600; /** * 棋盘中线与线之间的距离 */ private static final int PADDING = 40; /** * 棋盘与边框之间的距离 */ private static final int MARGIN = 20; /** * 棋盘中水平线与垂直线的个数 */ private static final int LINE_COUNT = 14; /** * 棋盘对象 */ private Pane pane; /** * 当前落子是否为黑子 */ private boolean isBlack = true; /** * 记录棋盘 */ private Chess[][] chesses = new Chess[LINE_COUNT][LINE_COUNT]; /** * 记录棋子顺序 */ private Chess[] cs = new Chess[LINE_COUNT * LINE_COUNT]; /** * 棋盘上棋子个数 */ private int count = 0; /** * 是否胜利 */ private boolean isWin = false; /** * 舞台对象 */ private Stage stage; @Override public void start(Stage stage) { this.stage = stage; // 获取画板对象 this.pane = getPane(); // 落子 moveInChess(); // 创建场景对象 Scene scene = new Scene(pane, WIDTH, HEIGHT); stage.setScene(scene); stage.setTitle("五子棋"); stage.setOnCloseRequest(event -> { Alert alert = new Alert(AlertType.CONFIRMATION); alert.setTitle("退出"); alert.setHeaderText("确认提出吗?"); Optional<ButtonType> optional = alert.showAndWait(); if (optional.isPresent() && optional.get() == ButtonType.CANCEL) { event.consume(); } }); stage.show(); } /** * 落子功能 */ private void moveInChess() { // 给画板对象绑定鼠标点击事件 pane.setOnMouseClicked(event -> { if (isWin) { return; } // 获取鼠标点击的坐标 double x = event.getX(); double y = event.getY(); // System.out.println(x + " " + y); if (!(x >= MARGIN && x <= MARGIN + (LINE_COUNT - 1) * PADDING && y >= MARGIN && y <= MARGIN + (LINE_COUNT - 1) * PADDING)) { return; } // 根据鼠标点击位置计算棋子坐标 int chessX = ((int) x - MARGIN + PADDING / 2) / PADDING; int chessY = ((int) y - MARGIN + PADDING / 2) / PADDING; // System.out.println(_x + " " + _y); if (chesses[chessX][chessY] != null) { // System.out.println("已经有棋子了"); return; } // 绘制棋子 Chess chess = drawChess(chessX, chessY); if (isWin(chess)) { Alert alert = new Alert(AlertType.INFORMATION); alert.setTitle("游戏结束"); String name; if (chess.getColor() == Color.BLACK) { name = "黑子"; } else { name = "白子"; } alert.setHeaderText(name + "胜利了"); alert.showAndWait(); isWin = true; } }); } /** * 绘制棋子 */ private Chess drawChess(int chessX, int chessY) { Circle circle; Chess chess; if (isBlack) { circle = new Circle(chessX * PADDING + MARGIN, chessY * PADDING + MARGIN, 15, Color.BLACK); chess = new Chess(chessX, chessY, Color.BLACK); isBlack = false; } else { circle = new Circle(chessX * PADDING + MARGIN, chessY * PADDING + MARGIN, 15, Color.WHITE); chess = new Chess(chessX, chessY, Color.WHITE); isBlack = true; } chesses[chessX][chessY] = chess; cs[count++] = chess; pane.getChildren().add(circle); return chess; } /** * 创建画板对象 */ private Pane getPane() { // 创建画板对象 Pane pane = new Pane(); // 设置画板背景颜色 pane.setBackground(new Background(new BackgroundFill(Color.BEIGE, null, null))); // 绘制棋盘 int increment = 0; for (int i = 0; i < LINE_COUNT; i++) { Line rowLine = new Line(MARGIN, MARGIN + increment, MARGIN + (LINE_COUNT - 1) * PADDING, MARGIN + increment); Line colLine = new Line(MARGIN + increment, MARGIN, MARGIN + increment, MARGIN + (LINE_COUNT - 1) * PADDING); pane.getChildren().add(rowLine); pane.getChildren().add(colLine); increment += PADDING; } // 再来一局按钮 Button startButton = getStartButton(); // 悔棋按钮 Button retractButton = getRetractButton(); // 退出按钮 Button quitButton = getQuitButton(); // 保存棋谱按钮 Button saveButton = getSaveButton(); // 保存打谱按钮 Button scoreButton = getScoreButton(); pane.getChildren().add(startButton); pane.getChildren().add(retractButton); pane.getChildren().add(quitButton); pane.getChildren().add(saveButton); pane.getChildren().add(scoreButton); return pane; } /** * 获取打谱按钮 */ private Button getScoreButton() { Button scoreButton = new Button("棋谱复盘"); scoreButton.setPrefSize(80, 30); scoreButton.setLayoutX(WIDTH / 15.0 + 100 * 3); scoreButton.setLayoutY(HEIGHT - 40); scoreButton.setOnAction(event -> { FileChooser fileChooser = new FileChooser(); fileChooser.getExtensionFilters().addAll(new ExtensionFilter("棋谱文件", "*.qipu"), new ExtensionFilter("所有文件", "*.*")); File file = fileChooser.showOpenDialog(stage); if (file == null) { return; } try { BufferedReader br = new BufferedReader(new FileReader(file)); String line; ArrayList<String> cheesiness = new ArrayList<>(); while ((line = br.readLine()) != null) { cheesiness.add(line); } br.close(); resetChessBoard(); Button next = new Button(">"); next.setPrefSize(40, 40); next.setLayoutX(WIDTH - 40); next.setLayoutY(100); next.setOnAction(event13 -> { if (count >= cheesiness.size()) { Alert alert = new Alert(AlertType.INFORMATION); alert.setTitle("提示"); alert.setHeaderText("没有下一步了"); alert.showAndWait(); return; } String[] info = cheesiness.get(count).split(","); drawChess(Integer.parseInt(info[0]), Integer.parseInt(info[1])); }); pane.getChildren().add(next); Button pre = new Button("<"); pre.setPrefSize(40, 40); pre.setLayoutX(WIDTH - 40); pre.setLayoutY(150); pre.setOnAction(event12 -> retract()); pane.getChildren().add(pre); Button exit = new Button("x"); exit.setPrefSize(40, 40); exit.setLayoutX(WIDTH - 40); exit.setLayoutY(200); exit.setOnAction(event1 -> { Alert alert = new Alert(AlertType.CONFIRMATION); alert.setTitle("提示"); alert.setHeaderText("确定退出打谱?"); Optional<ButtonType> optional = alert.showAndWait(); if (optional.isPresent() && optional.get() == ButtonType.OK) { resetChessBoard(); pane.getChildren().remove(pane.getChildren().size() - 3, pane.getChildren().size()); } }); pane.getChildren().add(exit); } catch (IOException e) { e.printStackTrace(); } }); return scoreButton; } /** * 获取保存棋谱按钮 */ private Button getSaveButton() { Button saveButton = new Button("保存棋谱"); saveButton.setPrefSize(80, 30); saveButton.setLayoutX(WIDTH / 15.0 + 100 * 2); saveButton.setLayoutY(HEIGHT - 40); saveButton.setOnAction(event -> { FileChooser fileChooser = new FileChooser(); fileChooser.getExtensionFilters().addAll(new ExtensionFilter("棋谱文件", "*.qipu"), new ExtensionFilter("所有文件", "*.*")); File file = fileChooser.showSaveDialog(stage); if (file == null) { return; } try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) { for (int i = 0; i < count; i++) { bw.write(cs[i].getX() + "," + cs[i].getY() + "," + cs[i].getColor()); bw.newLine(); } } catch (IOException e) { e.printStackTrace(); } }); return saveButton; } /** * 获取退出按钮 */ private Button getQuitButton() { Button quitButton = new Button("退出"); quitButton.setPrefSize(80, 30); quitButton.setLayoutX(WIDTH / 15.0 + 100 * 4); quitButton.setLayoutY(HEIGHT - 40); quitButton.setOnAction(event -> { Alert alert = new Alert(AlertType.CONFIRMATION); alert.setTitle("退出"); alert.setHeaderText("确认提出吗?"); Optional<ButtonType> optional = alert.showAndWait(); if (optional.isPresent() && optional.get() == ButtonType.OK) { System.exit(0); } }); return quitButton; } /** * 获取悔棋按钮 */ private Button getRetractButton() { Button retractButton = new Button("悔棋"); retractButton.setPrefSize(80, 30); retractButton.setLayoutX(WIDTH / 15.0 + 100); retractButton.setLayoutY(HEIGHT - 40); retractButton.setOnAction(event -> retract()); return retractButton; } /** * 获取再来一局按钮 */ private Button getStartButton() { // 添加按钮对象 Button startButton = new Button("再来一局"); startButton.setPrefSize(80, 30); startButton.setLayoutX(WIDTH / 15.0); startButton.setLayoutY(HEIGHT - 40); // 给按钮对象绑定鼠标点击事件 startButton.setOnAction(event -> resetChessBoard()); return startButton; } /** * 悔棋 */ private void retract() { if (isWin) { return; } if (count > 0) { pane.getChildren().remove(pane.getChildren().size() - 1); isBlack = !isBlack; Chess chess = cs[--count]; chesses[chess.getX()][chess.getY()] = null; cs[count] = null; } } /** * 重置棋盘 */ private void resetChessBoard() { pane.getChildren().removeIf((Predicate<Object>) t -> t instanceof Circle); count = 0; chesses = new Chess[LINE_COUNT][LINE_COUNT]; cs = new Chess[LINE_COUNT * LINE_COUNT]; isBlack = true; isWin = false; } /** * 判断胜负 */ private boolean isWin(Chess chess) { int x = chess.getX(); int y = chess.getY(); Color color = chess.getColor(); // 向右横向判断 for (int i = x + 1; i <= x + 4 && i < LINE_COUNT; i++) { Chess c = chesses[i][y]; if (c == null || !color.equals(c.getColor())) { break; } if (i == x + 4) { return true; } } // 向左横向判断 for (int i = x - 1; i >= x - 4 && i >= 0; i--) { Chess c = chesses[i][y]; if (c == null || !color.equals(c.getColor())) { break; } if (i == x - 4) { return true; } } // 向上纵向判断 for (int i = y - 1; i >= y - 4 && i >= 0; i--) { Chess c = chesses[x][i]; if (c == null || !color.equals(c.getColor())) { break; } if (i == y - 4) { return true; } } // 向下纵向判断 for (int i = y + 1; i <= y + 4 && i < LINE_COUNT; i++) { Chess c = chesses[x][i]; if (c == null || !color.equals(c.getColor())) { break; } if (i == y + 4) { return true; } } // 向右上斜向判断 for (int i = x + 1, j = y - 1; i <= x + 4 && j >= y - 4 && i < LINE_COUNT && j >= 0; i++, j--) { Chess c = chesses[i][j]; if (c == null || !color.equals(c.getColor())) { break; } if (i == x + 4 && j == y - 4) { return true; } } // 向左上斜向判断 for (int i = x - 1, j = y - 1; i >= x - 4 && j >= y - 4 && i >= 0 && j >= 0; i--, j--) { Chess c = chesses[i][j]; if (c == null || !color.equals(c.getColor())) { break; } if (i == x - 4 && j == y - 4) { return true; } } // 向左下斜向判断 for (int i = x - 1, j = y + 1; i >= x - 4 && j <= y + 4 && i >= 0 && j < LINE_COUNT; i--, j++) { Chess c = chesses[i][j]; if (c == null || !color.equals(c.getColor())) { break; } if (i == x - 4 && j == y + 4) { return true; } } // 向右下斜向判断 for (int i = x + 1, j = y + 1; i <= x + 4 && j <= y + 4 && i < LINE_COUNT && j < LINE_COUNT; i++, j++) { Chess c = chesses[i][j]; if (c == null || !color.equals(c.getColor())) { break; } if (i == x + 4 && j == y + 4) { return true; } } return false; } public static void main(String[] args) { launch(args); } }
2022年04月04日
58 阅读
0 评论
2 点赞
2022-03-19
java中的接口
接口的定义:interface 接口名{ ... }接口就是一个特殊的类接口中不能有字段,但可以有常量,默认被public static final修饰:interface X{ int a = 1; }等价于interface X{ public static final int a = 1; }接口的方法:1.接口中的所有方法,默认被public abstract修饰,也就是说接口中的所有方法都是抽象方法。interface X{ void f1(); }等价于interface X{ public abstract void f1(); }2.接口中也可以定义普通方法:interface X { void f1() { ... } }注意:Java中,有一个规范,当一个变量同时被static和final修饰的时候,该变量的名字中的所有字母都应该时大写的,单词和单词之间用 "_" 隔开。例:interface X{ String MY_NAME = "第一帅"; static final int HER_AGE = 20; final double HIS_SALARY = 30000; }接口无法被实例化,因为接口中的方法都是抽象的。接口的实现:class 类名 implements 接口名{ //实现接口的所有抽象方法 }接口中的抽象方法,在非抽象子类中,必须全部得以实现:interface I{ void aa(); //接口中的方法。默认被public修饰 } class A implements I{ public void aa(){ //所以子类重写方法时,访问修饰符也必须是public System.out.println("A.aa()"); } }一个类只能继承一个类,但一个类可实现多个接口:interface A{ void aa(); } interface B{ void aa(); void bb(); } class X implements A, B{ public void aa(){ //一个类实现两个接口, //两个接口的抽象方法必须全部实现 } //如果多个接口出现了相同的方法, public void bb(){ //只实现一次即可 } }一个类在继承一个类的同时,可以再去实现其他多个接口:class X extends A implements B, C{ }一个类实现一个接口,是一种比较特殊的“继承”关系,所以也能发生向上转型:interface A{ } class X implements A{ } public class Test{ public static void main(String[] args){ X x = new X(); A a = new X(); //这里发生了向上转型 } }接口的扩展接口和接口之间,时多继承的关系,也就是说,一个接口可以继承其他多个接口,等价于汇总了多个接口中的所有抽象方法到一个接口中:interface A{ void aa(); } interface B{ void bb(); } interface C extends A, B{ } class X implements C{ //接口C没有任何抽象方法, public void aa(){ //但它继承了A和B中的所有抽象方法 } public void bb(){ } }
2022年03月19日
23 阅读
0 评论
0 点赞
2022-03-15
java中类的设计技巧
1. 一定要保证数据私有这是最重要的;绝对不要破坏封装性。2. 一定要对数据进行初始化Java 不会为你初始化局部变量,但是会对对象的实例字段进行初始化。最好不要依赖于系统的默认值,而是应该显式地初始化所有的数据,可以提供默认值,也可以在所有构造器中设置默认值。3. 不要在类中使用过多的基本类型这个想法是要用其他地类替换使用多个相关的基本类型。这样会使类更易于理解,也更易于修改。例如,用一个 Address 的新类替换一个 Customer 类中的以下实例字段:class Customer { private String street; private String city; private String state; private int zip; }class Address { private String street; private String city; private String state; private int zip } class Customer { private Address address; }4. 不是所有的字段都需要单独的字段访问器和字段更改器在对象中,常常包含一些不希望别人获得或设置的实例字段。5. 分解有过多职责的类。6. 类名和方法名要能够体现它们的职责7. 优先使用不可变的类不可变类——没有方法能修改对象的状态。方法并不是更改对象,而是返回 状态已修改的新对象。更改对象的问题在于,如果多个线程试图同时更新一个对象,就会发生并发更改,其结果是不可预料的。如果类是不可变的,就可以安全地在多个线程间共享其对象。当然,并不是所有类都应当是不可变的,如果员工加薪时让 raiseSalary 方法返回一个新的 Employee 对象,这会很奇怪。
2022年03月15日
35 阅读
0 评论
0 点赞
2022-03-02
Java中的大数
java中的基本类型表示数值的有整型和浮点型,而它们都有范围,当我们的数值特别大时,就要用到大数。
2022年03月02日
39 阅读
0 评论
0 点赞
1
2
3
...
5