一、Java基础_入门-12_通过命令行给main()方法传参&可变参数&递归&数组
命令行传参(通过命令行给main()方法传参)
有时候你希望运行一个程序时候在传递给它消息。这时候要靠传递命令行参数给main()函数实现。(通过”命令提示符“给main()方法传参 / 在idea的”terminal“界面运行Java给main()方法传参)
在"要运行的java文件"所在的目录运行"javac指令",即在other目录中运行javac Test.java
在"要运行的Java文件所在包 的上层目录"中运行"java指令",即在java目录中运行java cn.companyname.javase8.test.other.Test
可变参数
背景:JDK 1.5开始,Java 提供了 “可变参数/变长参数” ,允许在调用方法时传入不定长度的参数。变长参数是 Java 的一个语法糖,本质上还是基于数组的实现。
定义方法:在定义方法时,在最后一个形参后加上三点 … ,就表示该形参可以接受多个参数值,多个参数值被当成数组传入。
上述定义有几个要点需要注意:
1. 可变参数只能作为函数的最后一个参数,但其前面可以有也可以没有任何其他参数
2.由于可变参数必须是最后一个参数,所以一个函数最多只能有一个可变参数
3. Java的可变参数,会被编译器转型为一个数组
4. 变长参数在编译为字节码后,在方法签名(方法声明的两个组件构成了 方法签名 —— 方法的名称、参数类型)中就是以数组形态出现的。若果两个方法的签名是一致的,同时出现在类中,是不能编译通过的(不能作为方法的重载)。可变参数可以兼容数组,反之则不成立。
使用场景:在不确定方法需要处理的对象的数量时可以使用可变长参数,会使得方法调用更简单,无需手动创建数组 new T[ ]{…}
递归:
递归就是:A方法调用A方法!就是自己调用自己。
作用:利用递归可以用简单的程序来解决一些复杂的问题。它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。
递归结构包括两个部分:
递归头:什么时候不调用自身方法。如果没有头,将陷入死循环 ——> 。
递归体:什么时候需要调用自身方法。
“以此类推”是递归的基本思想。
具体来讲就是把规模大的问题转化为规模小的相似的子问题来解决。在函数实现时,因为解决大问题的方法和解决小问题的方法往往是同一个方法,所以就产生了函数调用它自身的情况。另外这个解决问题的函数必须有明显的结束条件,这样就不会产生无限递归的情况了。
递归需要满足的三个条件:
1. 一个问题的解可以分解为几个子问题的解;2. 这个问题与分解之后的子问题,除了数据规模不同,求解思路完全一样;3. 存在递归终止条件。
递归的过程
我们会惊奇的发现这个过程和 栈 的工作原理一致,递归调用就是通过 栈 这种数据结构完成的。整个过程实际上就是一个栈的入栈和出栈问题。然而我们并不需要关心这个栈的实现,这个过程是由系统来完成的。
那么递归中的“递”就是入栈,递进;“归”就是出栈,回归。
Java中不合理的使用递归调用,可能会导致栈内存溢出,这点是需要注意的。
栈溢出:什么情况下才会发生 栈溢出 呢? 原文链接:https://zhuanlan.zhihu.com/p/73411916
最常见的就是递归。每次递归就相当于调用一个函数,函数每次被调用时都会将局部数据(在函数内部定义的变量、参数、数组、对象等)放入栈中。
递归1000次,就会将1000份这样的数据放入栈中。这些数据占用的内存直到整个递归结束才会被释放,在递归过程中只会累加,不会释放。如果递归次数过多,并且局部数据也多,那么会使用大量的栈内存,很容易就导致栈溢出了。(调用方法的次数叫深度)
归其实是方便了程序员难为了机器,递归可以通过数学公式很方便的转换为程序。其优点就是易理解,容易编程。但递归是用栈机制实现的,每深入一层,都要占去一块栈数据区域,对嵌套层数深的一些算法,递归会力不从心,空间上会以内存崩溃而告终,而且递归也带来了大量的函数调用,这也有许多额外的时间开销。所以在深度大时,它的时空性就不好了。(会占用大量的内存空间)
而迭代虽然效率高,运行时间只因循环次数增加而增加,没什么额外开销,空间上也没有什么增加,但缺点就是不容易理解,编写复杂问题时困难。能不用递归就不用递归,递归都可以用迭代来代替。(要辩证的看待这个问题,深度不大,还是可以采用递归的)。
数组
普通数组:
声明数组 变量的语法:
DataType[ ] arrayRefVar; // 首选的方法
DataType arrayRefVar[ ]; // 效果相同,但不是首选方法
创建数组:
DataType[ ] arrayRefVar = new DataType[ arraySize ];
DataType[ ] arrayRefVar = { value0, value1, ..., valuek };
DataType[ ] a = new DataType[ ] { value0, value1, ..., valuek };
二维数组:
创建: DataType[ ][ ] typeName = new DataType[ typeLength1 ][ typeLength2 ];
Arrays 类:
java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的。