JAVA空控制台学习笔记

x33g5p2x  于2021-11-22 转载在 Java  
字(10.7k)|赞(0)|评价(0)|浏览(361)

ArrayList于LinkList(链表)

  • 首先讲解一下LinkList,我们之前讲过动态数组ArrayList,ArrayList基于动态数组实现的非线程安全的集合;LinkedList基于链表实现的非线程安全的集合。
  • 对于随机index访问的get和set方法,一般ArrayList的速度要优于LinkedList。因为ArrayList直接通过数组下标直接找到元素;LinkedList要移动指针遍历每个元素直到找到为止。
  • 新增和删除元素,一般LinkedList的速度要优于ArrayList。因为ArrayList在新增和删除元素时,可能扩容和复制数组;LinkedList实例化对象需要时间外,只需要修改指针即可。
  • LinkedList集合不支持 高效的随机随机访问(RandomAccess)
  • ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间

我们要使用java实现一个多级菜单,显而易见需要用到树形结构,那么怎样去写一个树形结构呢?

首先:我们创建一个TreeNode类:然后写一个Node的内部类:

  1. public static class Node<T>{
  2. private T data = null;
  3. private List<Node<T>> children = new ArrayList<>();
  4. private Node<T> parent = null;
  5. }

接下来我们需要为他构建方法和设置get set方法:

  1. public Node(T data) {
  2. this.data = data;
  3. }
  4. public T getData() {
  5. return data;
  6. }
  7. public void setData(T data) {
  8. this.data = data;
  9. }
  10. public List<Node<T>> getChildren() {
  11. return children;
  12. }
  13. public void setChildren(List<Node<T>> children) {
  14. this.children = children;
  15. }
  16. public Node<T> getParent() {
  17. return parent;
  18. }
  19. public void setParent(Node<T> parent) {
  20. this.parent = parent;
  21. }
  22. /** * 定义增加单个子节点的方法 */
  23. public Node<T> addChild(Node<T> child){
  24. child.setParent(this); //this代表children对象本身
  25. this.children.add(child);
  26. return child;
  27. }
  28. /** *添加多个子节点 */
  29. public void addChildren(List<Node<T>> children) {
  30. children.forEach(each -> each.setParent(this));
  31. this.children.addAll(children);
  32. }

这里插入一下lambda表达式的讲解:

说白了就是 ->这个符号 前面写参数后面写方法:

  1. // 1. 不需要参数,返回值为 5
  2. () -> 5
  3. // 2. 接收一个参数(数字类型),返回其2倍的值
  4. x -> 2 * x
  5. // 3. 接受2个参数(数字),并返回他们的差值
  6. (x, y) -> x y
  7. // 4. 接收2个int型整数,返回他们的和
  8. (int x, int y) -> x + y
  9. // 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
  10. (String s) -> System.out.print(s)

然后我们需要往这个树里面添加节点,那么怎样添加呢?举个粒子:

  1. Node<String> node1_china = new Node<String>("1.中国");

首先新建一个顶节点:node1_china,然后为这个顶节点添加一个子节点:

  1. Node<String> node1_1 = node1_china.addChild(new Node<String>("1.北京"));

这里的北京就是一个子节点使用了上面的addChild方法

  1. Node<String> node1_1 = node1_china.addChild(new Node<String>("1.北京"));

不断的按照梯形去添加新的节点:

  1. Node<String> node1_china = new Node<String>("1.中国");
  2. Node<String> node1_1 = node1_china.addChild(new Node<String>("1.北京"));
  3. Node<String> node1_1_1 = node1_1.addChild(new Node<String>("1.朝阳区")) ;
  4. Node<String> node1_1_2 = node1_1.addChild(new Node<String>("2.海定区"));
  5. Node<String> node1_1_3 = node1_1.addChild(new Node<String>("3.昌平区"));
  6. Node<String> node1_2 = node1_china.addChild(new Node<String>("2.湖北"));
  7. Node<String> node1_2_1 = node1_2.addChild(new Node<String>("1.武汉市")) ;
  8. Node<String> node1_2_2 = node1_2.addChild(new Node<String>("2.襄樊市"));
  9. Node<String> node1_2_3 = node1_2.addChild(new Node<String>("3.咸宁市"));
  10. Node<String> node1_3 = node1_china.addChild(new Node<String>("3.湖南"));
  11. Node<String> node1_3_1 = node1_3.addChild(new Node<String>("1.长沙市")) ;
  12. Node<String> node1_3_2 = node1_3.addChild(new Node<String>("2.株洲市"));
  13. Node<String> node1_3_3 = node1_3.addChild(new Node<String>("3.湘潭市"));
  14. Node<String> node2_USA = new Node<String>("2.美国");
  15. Node<String> node2_1 = node2_USA.addChild(new Node<String>("1.纽约市") ) ;
  16. Node<String> node2_1_1 = node2_1.addChild(new Node<String>("1.曼哈顿"));
  17. Node<String> node2_1_2 = node2_1.addChild(new Node<String>("2.布鲁克林"));
  18. Node<String> node2_1_3 = node2_1.addChild(new Node<String>("3.皇后区"));
  19. Node<String> node2_2 = node2_USA.addChild(new Node<String>("2.德克萨斯") ) ;
  20. Node<String> node2_2_1 = node2_2.addChild(new Node<String>("1.奥斯汀"));
  21. Node<String> node2_2_2 = node2_2.addChild(new Node<String>("2.休斯顿"));
  22. Node<String> node2_2_3 = node2_2.addChild(new Node<String>("3.达拉斯"));
  23. Node<String> node2_3 = node2_USA.addChild(new Node<String>("3.加利福尼亚") ) ;
  24. Node<String> node2_3_1 = node2_3.addChild(new Node<String>("1.洛杉矶"));
  25. Node<String> node2_3_2 = node2_3.addChild(new Node<String>("2.旧金山"));
  26. Node<String> node2_3_3 = node2_3.addChild(new Node<String>("3.奥克兰"));

然后我们再定义一个顶尖节点,将两个定点放入:

  1. Node<String> rootNode = new Node<String>("");
  2. rootNode.addChild(node1_china);
  3. rootNode.addChild(node2_USA);

接下来就需要要写打印输出的方法了:

为了可以有阶梯感,我们再构造打印方法的时候需要传入两个参数,一个就是要打印的树另一个是一个空格:

  1. public static void printTree(Node<String> node, String appender){
  2. System.out.println(appender+node.getData());
  3. node.getChildren().forEach(each -> printTree(each,appender+appender));
  4. }

全部代码:

  1. package 任务三;
  2. import 任务三.树形菜单.NewTest;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. /** * @author ${范涛之} * @Description * @create 2021-11-16 15:21 */
  6. public class TreeNode {
  7. public static class Node<T>{
  8. private T data = null;
  9. private List<Node<T>> children = new ArrayList<>();
  10. private Node<T> parent = null;
  11. public Node(T data) {
  12. this.data = data;
  13. }
  14. public T getData() {
  15. return data;
  16. }
  17. public void setData(T data) {
  18. this.data = data;
  19. }
  20. public List<Node<T>> getChildren() {
  21. return children;
  22. }
  23. public void setChildren(List<Node<T>> children) {
  24. this.children = children;
  25. }
  26. public Node<T> getParent() {
  27. return parent;
  28. }
  29. public void setParent(Node<T> parent) {
  30. this.parent = parent;
  31. }
  32. /** * 定义增加单个子节点的方法 */
  33. public Node<T> addChild(Node<T> child){
  34. child.setParent(this); //this代表children对象本身
  35. this.children.add(child);
  36. return child;
  37. }
  38. public void addChildren(List<Node<T>> children) {
  39. children.forEach(each -> each.setParent(this));
  40. this.children.addAll(children);
  41. }
  42. public static void main(String[] args) {
  43. Node<String> node1_china = new Node<String>("1.中国");
  44. Node<String> node1_1 = node1_china.addChild(new Node<String>("1.北京"));
  45. Node<String> node1_1_1 = node1_1.addChild(new Node<String>("1.朝阳区")) ;
  46. Node<String> node1_1_2 = node1_1.addChild(new Node<String>("2.海定区"));
  47. Node<String> node1_1_3 = node1_1.addChild(new Node<String>("3.昌平区"));
  48. Node<String> node1_2 = node1_china.addChild(new Node<String>("2.湖北"));
  49. Node<String> node1_2_1 = node1_2.addChild(new Node<String>("1.武汉市")) ;
  50. Node<String> node1_2_2 = node1_2.addChild(new Node<String>("2.襄樊市"));
  51. Node<String> node1_2_3 = node1_2.addChild(new Node<String>("3.咸宁市"));
  52. Node<String> node1_3 = node1_china.addChild(new Node<String>("3.湖南"));
  53. Node<String> node1_3_1 = node1_3.addChild(new Node<String>("1.长沙市")) ;
  54. Node<String> node1_3_2 = node1_3.addChild(new Node<String>("2.株洲市"));
  55. Node<String> node1_3_3 = node1_3.addChild(new Node<String>("3.湘潭市"));
  56. Node<String> node2_USA = new Node<String>("2.美国");
  57. Node<String> node2_1 = node2_USA.addChild(new Node<String>("1.纽约市") ) ;
  58. Node<String> node2_1_1 = node2_1.addChild(new Node<String>("1.曼哈顿"));
  59. Node<String> node2_1_2 = node2_1.addChild(new Node<String>("2.布鲁克林"));
  60. Node<String> node2_1_3 = node2_1.addChild(new Node<String>("3.皇后区"));
  61. Node<String> node2_2 = node2_USA.addChild(new Node<String>("2.德克萨斯") ) ;
  62. Node<String> node2_2_1 = node2_2.addChild(new Node<String>("1.奥斯汀"));
  63. Node<String> node2_2_2 = node2_2.addChild(new Node<String>("2.休斯顿"));
  64. Node<String> node2_2_3 = node2_2.addChild(new Node<String>("3.达拉斯"));
  65. Node<String> node2_3 = node2_USA.addChild(new Node<String>("3.加利福尼亚") ) ;
  66. Node<String> node2_3_1 = node2_3.addChild(new Node<String>("1.洛杉矶"));
  67. Node<String> node2_3_2 = node2_3.addChild(new Node<String>("2.旧金山"));
  68. Node<String> node2_3_3 = node2_3.addChild(new Node<String>("3.奥克兰"));
  69. Node<String> rootNode = new Node<String>("");
  70. rootNode.addChild(node1_china);
  71. rootNode.addChild(node2_USA);
  72. printTree(rootNode," ");
  73. }
  74. public static void printTree(Node<String> node, String appender){
  75. System.out.println(appender+node.getData());
  76. node.getChildren().forEach(each -> printTree(each,appender+appender));
  77. }
  78. }
  79. }

心得:

这道题自己确实还是很不熟悉,感觉到了最后在用到遍历的时候还有Lambda表达式很生疏,现在自己理解一下:这是一个先输出再遍历的方法, System.out.println(appender+node.getData());这里输出了我们的数据data也就是我们最一开始定义的第一个子节点:node1_china,然后开始递归调用,通过foreach循环这个子节点的“子子”节点,“子子”节点的打印输出和最开始的node1_china使用同样的方式, node.getChildren().forEach(each -> printTree(each,appender+appender));也就是这行代码的后面那部分,我们创建了一个each临时变量来代替子节点、“子子”节点以及后面的“子子子节点”,通过->这个Lambda表达式,也就是“参数”->“方法”,实现遍历,这里的方法就是外面的printTree方法。

打印输出的版本:

  1. package 任务三;
  2. import java.util.Scanner;
  3. /** * @author ${范涛之} * @Description * @create 2021-11-16 21:51 */
  4. public class TestNode2 {
  5. public static void main(String[] args) {
  6. /** * 定义所有节点 */
  7. String s1 = "1.中国";
  8. String s1_1 = "1.北京";
  9. String s1_2 = "2.湖北";
  10. String s1_3 = "3.湖南";
  11. String s1_1_1 = "1.朝阳区";
  12. String s1_1_2 = "2.海淀区";
  13. String s1_1_3 = "3.昌平区";
  14. String s1_2_1 = "1.武汉市";
  15. String s1_2_2 = "2.襄樊市";
  16. String s1_2_3 = "3.咸宁市";
  17. String s1_3_1 = "1.长沙市";
  18. String s1_3_2 = "2.株洲市";
  19. String s1_3_3 = "3.湘潭市";
  20. String s2 = "2.美国";
  21. String s2_1 = "1.纽约州";
  22. String s2_2 = "2.德克萨斯";
  23. String s2_3 = "3.加利福尼亚";
  24. String s2_1_1 = "1.曼哈顿";
  25. String s2_1_2 = "2.布鲁克林";
  26. String s2_1_3 = "3.皇后区";
  27. String s2_2_1 = "1.奥斯汀";
  28. String s2_2_2 = "2.休斯顿";
  29. String s2_2_3 = "3.达拉斯";
  30. String s2_3_1 = "1.洛杉矶";
  31. String s2_3_2 = "2.旧金山";
  32. String s2_3_3 = "3.奥克兰";
  33. /** * 使用多维数组存放 */
  34. String[] country = {s1, s2};
  35. String[][] province = {{s1_1, s1_2, s1_3}, {s2_1, s2_2, s2_3}};
  36. String[][][] position = {
  37. {
  38. {s1_1_1, s1_1_2, s1_1_3},
  39. {s1_2_1, s1_2_2, s1_2_3},
  40. {s1_3_1, s1_3_2, s1_3_3},
  41. },
  42. {
  43. {s2_1_1, s2_1_2, s2_1_3},
  44. {s2_2_1, s2_2_2, s2_2_3},
  45. {s2_3_1, s2_3_2, s2_3_3},
  46. }
  47. };
  48. System.out.println("请输入国家编号: 1:中国--2:美国");
  49. Scanner scanner = new Scanner(System.in);
  50. int t1 = scanner.nextInt();
  51. while (true){
  52. if (t1!=1 && t1!=2){
  53. System.out.println("请输入1或者2");
  54. continue;
  55. }
  56. else {
  57. if (t1 == 1){
  58. System.out.println(country[0]);
  59. System.out.println("中国的省份有:1:北京 2:湖北 3:湖南");
  60. }else {
  61. System.out.println(country[1]);
  62. System.out.println("美国的省份有:1:纽约 2:德克萨斯 3:加利福尼亚");
  63. }
  64. break;
  65. }
  66. }
  67. System.out.println("请输入省份编号1-3");
  68. int t2 = scanner.nextInt();
  69. while (true){
  70. if (t2!=1 && t2!=2 && t2!=3){
  71. System.out.println("请输入1-3之间的数字");
  72. continue;
  73. }
  74. else {
  75. System.out.println(province[t1-1][t2-1]+"省的地区有:");
  76. for (String s: position[t1-1][t2-1]) {
  77. System.out.println(s);
  78. }
  79. break;
  80. }
  81. }
  82. System.out.println("请输入地区编号1-3");
  83. int t3 = scanner.nextInt();
  84. while (true){
  85. if (t3!=1 && t3!=2 && t3!= 3){
  86. System.out.println("请输入1-3之间的数");
  87. }
  88. else {
  89. System.out.println(position[t1-1][t2-1][t3-1]);
  90. }
  91. break;
  92. }
  93. }
  94. }

参考了另一位同学的代码并作出了改进:完善了输出:

分割线

管道命令理解:就是前面命令的输出结果作为后面命令的输入结果:

明日再看…

相关文章

最新文章

更多