JAVA空控制台学习笔记

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

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的内部类:

public  static  class  Node<T>{
        private T data = null;
        private List<Node<T>> children = new ArrayList<>();
        private  Node<T> parent = null;
        }

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

public Node(T data) {
            this.data = data;
        }

        public T getData() {
            return data;
        }

        public void setData(T data) {
            this.data = data;
        }

        public List<Node<T>> getChildren() {
            return children;
        }

        public void setChildren(List<Node<T>> children) {
            this.children = children;
        }

        public Node<T> getParent() {
            return parent;
        }

        public void setParent(Node<T> parent) {
            this.parent = parent;
        }
        /** * 定义增加单个子节点的方法 */
        public  Node<T> addChild(Node<T> child){
            child.setParent(this);  //this代表children对象本身
            this.children.add(child);
            return  child;
        }
        /** *添加多个子节点 */
        public void addChildren(List<Node<T>> children) {
            children.forEach(each -> each.setParent(this));
            this.children.addAll(children);
        }

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

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

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

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

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

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

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

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

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

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

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

            Node<String> node1_1 = node1_china.addChild(new Node<String>("1.北京"));
            
            Node<String> node1_1_1 = node1_1.addChild(new Node<String>("1.朝阳区")) ;
            Node<String> node1_1_2 = node1_1.addChild(new Node<String>("2.海定区"));
            Node<String> node1_1_3 = node1_1.addChild(new Node<String>("3.昌平区"));

            Node<String> node1_2 = node1_china.addChild(new Node<String>("2.湖北"));
            
            Node<String> node1_2_1 = node1_2.addChild(new Node<String>("1.武汉市")) ;
            Node<String> node1_2_2 = node1_2.addChild(new Node<String>("2.襄樊市"));
            Node<String> node1_2_3 = node1_2.addChild(new Node<String>("3.咸宁市"));

            
            Node<String> node1_3 = node1_china.addChild(new Node<String>("3.湖南"));
            
            Node<String> node1_3_1 = node1_3.addChild(new Node<String>("1.长沙市")) ;
            Node<String> node1_3_2 = node1_3.addChild(new Node<String>("2.株洲市"));
            Node<String> node1_3_3 = node1_3.addChild(new Node<String>("3.湘潭市"));



            Node<String> node2_USA = new Node<String>("2.美国");

            Node<String> node2_1 = node2_USA.addChild(new Node<String>("1.纽约市") ) ;
            
            Node<String> node2_1_1 = node2_1.addChild(new Node<String>("1.曼哈顿"));
            Node<String> node2_1_2 = node2_1.addChild(new Node<String>("2.布鲁克林"));
            Node<String> node2_1_3 = node2_1.addChild(new Node<String>("3.皇后区"));

            Node<String> node2_2 = node2_USA.addChild(new Node<String>("2.德克萨斯") ) ;
            
            Node<String> node2_2_1 = node2_2.addChild(new Node<String>("1.奥斯汀"));
            Node<String> node2_2_2 = node2_2.addChild(new Node<String>("2.休斯顿"));
            Node<String> node2_2_3 = node2_2.addChild(new Node<String>("3.达拉斯"));

            Node<String> node2_3 = node2_USA.addChild(new Node<String>("3.加利福尼亚") ) ;
            
            Node<String> node2_3_1 = node2_3.addChild(new Node<String>("1.洛杉矶"));
            Node<String> node2_3_2 = node2_3.addChild(new Node<String>("2.旧金山"));
            Node<String> node2_3_3 = node2_3.addChild(new Node<String>("3.奥克兰"));

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

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

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

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

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

全部代码:

package 任务三;

import 任务三.树形菜单.NewTest;

import java.util.ArrayList;
import java.util.List;

/** * @author ${范涛之} * @Description * @create 2021-11-16 15:21 */
public class TreeNode {
    public  static  class  Node<T>{
        private T data = null;
        private List<Node<T>> children = new ArrayList<>();
        private  Node<T> parent = null;

        public Node(T data) {
            this.data = data;
        }

        public T getData() {
            return data;
        }

        public void setData(T data) {
            this.data = data;
        }

        public List<Node<T>> getChildren() {
            return children;
        }

        public void setChildren(List<Node<T>> children) {
            this.children = children;
        }

        public Node<T> getParent() {
            return parent;
        }

        public void setParent(Node<T> parent) {
            this.parent = parent;
        }
        /** * 定义增加单个子节点的方法 */
        public  Node<T> addChild(Node<T> child){
            child.setParent(this);  //this代表children对象本身
            this.children.add(child);
            return  child;
        }
        public void addChildren(List<Node<T>> children) {
            children.forEach(each -> each.setParent(this));
            this.children.addAll(children);
        }

        public static void main(String[] args) {
            Node<String> node1_china = new Node<String>("1.中国");

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

            Node<String> node1_1_1 = node1_1.addChild(new Node<String>("1.朝阳区")) ;
            Node<String> node1_1_2 = node1_1.addChild(new Node<String>("2.海定区"));
            Node<String> node1_1_3 = node1_1.addChild(new Node<String>("3.昌平区"));

            Node<String> node1_2 = node1_china.addChild(new Node<String>("2.湖北"));

            Node<String> node1_2_1 = node1_2.addChild(new Node<String>("1.武汉市")) ;
            Node<String> node1_2_2 = node1_2.addChild(new Node<String>("2.襄樊市"));
            Node<String> node1_2_3 = node1_2.addChild(new Node<String>("3.咸宁市"));

            Node<String> node1_3 = node1_china.addChild(new Node<String>("3.湖南"));

            Node<String> node1_3_1 = node1_3.addChild(new Node<String>("1.长沙市")) ;
            Node<String> node1_3_2 = node1_3.addChild(new Node<String>("2.株洲市"));
            Node<String> node1_3_3 = node1_3.addChild(new Node<String>("3.湘潭市"));



            Node<String> node2_USA = new Node<String>("2.美国");

            Node<String> node2_1 = node2_USA.addChild(new Node<String>("1.纽约市") ) ;

            Node<String> node2_1_1 = node2_1.addChild(new Node<String>("1.曼哈顿"));
            Node<String> node2_1_2 = node2_1.addChild(new Node<String>("2.布鲁克林"));
            Node<String> node2_1_3 = node2_1.addChild(new Node<String>("3.皇后区"));

            Node<String> node2_2 = node2_USA.addChild(new Node<String>("2.德克萨斯") ) ;

            Node<String> node2_2_1 = node2_2.addChild(new Node<String>("1.奥斯汀"));
            Node<String> node2_2_2 = node2_2.addChild(new Node<String>("2.休斯顿"));
            Node<String> node2_2_3 = node2_2.addChild(new Node<String>("3.达拉斯"));

            Node<String> node2_3 = node2_USA.addChild(new Node<String>("3.加利福尼亚") ) ;

            Node<String> node2_3_1 = node2_3.addChild(new Node<String>("1.洛杉矶"));
            Node<String> node2_3_2 = node2_3.addChild(new Node<String>("2.旧金山"));
            Node<String> node2_3_3 = node2_3.addChild(new Node<String>("3.奥克兰"));

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

            printTree(rootNode," ");

        }

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

心得:

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

打印输出的版本:

package 任务三;

import java.util.Scanner;

/** * @author ${范涛之} * @Description * @create 2021-11-16 21:51 */
public class TestNode2 {
    public static void main(String[] args) {
        /** * 定义所有节点 */
        String s1 = "1.中国";
        String s1_1 = "1.北京";
        String s1_2 = "2.湖北";
        String s1_3 = "3.湖南";
        String s1_1_1 = "1.朝阳区";
        String s1_1_2 = "2.海淀区";
        String s1_1_3 = "3.昌平区";
        String s1_2_1 = "1.武汉市";
        String s1_2_2 = "2.襄樊市";
        String s1_2_3 = "3.咸宁市";
        String s1_3_1 = "1.长沙市";
        String s1_3_2 = "2.株洲市";
        String s1_3_3 = "3.湘潭市";
        String s2 = "2.美国";
        String s2_1 = "1.纽约州";
        String s2_2 = "2.德克萨斯";
        String s2_3 = "3.加利福尼亚";
        String s2_1_1 = "1.曼哈顿";
        String s2_1_2 = "2.布鲁克林";
        String s2_1_3 = "3.皇后区";
        String s2_2_1 = "1.奥斯汀";
        String s2_2_2 = "2.休斯顿";
        String s2_2_3 = "3.达拉斯";
        String s2_3_1 = "1.洛杉矶";
        String s2_3_2 = "2.旧金山";
        String s2_3_3 = "3.奥克兰";

        /** * 使用多维数组存放 */

        String[] country = {s1, s2};
        String[][] province = {{s1_1, s1_2, s1_3}, {s2_1, s2_2, s2_3}};
        String[][][] position = {
                {
                        {s1_1_1, s1_1_2, s1_1_3},
                        {s1_2_1, s1_2_2, s1_2_3},
                        {s1_3_1, s1_3_2, s1_3_3},
                },
                {
                        {s2_1_1, s2_1_2, s2_1_3},
                        {s2_2_1, s2_2_2, s2_2_3},
                        {s2_3_1, s2_3_2, s2_3_3},
                }
        };

        System.out.println("请输入国家编号: 1:中国--2:美国");

        Scanner scanner = new Scanner(System.in);
        int t1 = scanner.nextInt();
        while (true){
            if (t1!=1 && t1!=2){
                System.out.println("请输入1或者2");
                continue;
            }
            else {
                if (t1 == 1){
                    System.out.println(country[0]);
                    System.out.println("中国的省份有:1:北京 2:湖北 3:湖南");
                }else {
                    System.out.println(country[1]);
                    System.out.println("美国的省份有:1:纽约 2:德克萨斯 3:加利福尼亚");
                }

                break;
            }
        }

        System.out.println("请输入省份编号1-3");

        int t2 = scanner.nextInt();
        while (true){
            if (t2!=1 && t2!=2 && t2!=3){
                System.out.println("请输入1-3之间的数字");
                continue;
            }
            else {
                System.out.println(province[t1-1][t2-1]+"省的地区有:");
                for (String s: position[t1-1][t2-1]) {
                    System.out.println(s);
                }
                break;
            }
        }
        System.out.println("请输入地区编号1-3");

        int t3 = scanner.nextInt();
        while (true){
            if (t3!=1 && t3!=2 && t3!= 3){
                System.out.println("请输入1-3之间的数");
            }
            else {
                System.out.println(position[t1-1][t2-1][t3-1]);
            }
            break;
        }

    }

}

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

分割线

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

明日再看…

相关文章