Java方法
System.out.println(),那么它是什么呢?
System
“类”.out
“输出对象”.println()
“方法”
- Java方法是语句的集合,它们在一起执行一个功能。
- 方法是解决一类问题的步骤的有序组合
- 方法包含于类或对象中
- 方法在程序中被创建,在其他地方被引用
- 设计方法的原则:方法的本意是功能块,就是实现某个功能的语句块的集合。我们设计方法的时候,最好保持方法的原子性,就是一个方法只完成1个功能,这样利于我们后期的扩展。
- main尽量干净简洁,把公共模块提取到外面,利用方法调用。
回顾:方法的命名规则?
加法练习:
public static void/*代表空类型*/ main(String[] args) {
//实际参数,实际调用传输给他的参数
int sum = add(1,2);
System.out.println(sum);
}//形式参数,用来定义作用的
public static int/*返回类型*/ add(int a,int b){
return a+b;//返回值
}
1. 方法的定义
Java的方法类似于其它语言的函数,是一段用于完成特定功能的代码片段,一般情况下,定义一个方法包含以下语法
方法包含一个方法头和一个方法体。下面是一个方法的所有部分:
修饰符:修饰符,这是可以选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
返回值类型:
1.有返回值类型:如果这个方法有返回值,那么定义方法时必须指定返回数据的数据类型。如:public double ad();
2.无返回值类型:void表示调用方法后无返回数据。里面可以写return语句,也可以不写。当return;时,后面没有写返回数据时,仅仅表示方法体的结束。如:public void ad();
方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
形式参数:在方法被调用时用于接收外界输入的数据。
实参:调用方法时实际传给方法的数据。
方法体:方法体包含具体的语句,定义该方法的功能。
修饰符 返回值类型 方法名(参数类型 参数名){
...
方法体
...
return 返回值;
}
示例:
import java.util.Scanner;
class AddFunctionDemo{
//主方法
public static void main(String[] args){
//创建键盘录入对象
Scanner scanner = new Scanner(System.in);
//提示并接收数据
System.out.println("请输入第一个数据:");
int num1 = scanner.nextInt();
System.out.println("请输入第二个数据:");
int num2 = scanner.nextInt();
//赋值调用add方法
int result = add(num1,num2);
//输出结果
System.out.println("两个数据的和为:"+result);
}
//自定义方法
/*
两个明确:
1.方法返回值类型(int类型)
2.参数类型及参数个数(参数类型:int,参数个数:2个)
*/
public static int add(int a,int b){
int sum = a+ b ;
return sum;
}
}
2. 方法调用
- 调用方法:对象名.方法名(实参列表)
- Java 支持两种调用方法的方式,根据方法是否返回值来选择。
1.当方法返回一个值的时候,方法调用通常被当做一个值。例如:
int larger = max(10,20);
2.如果方法返回值是 void ,方法调用一定是一条语句。
System.out.println("Hello,kuangshen!");
拓展:
- 值传递(pass by value):在调用函数时,将实际参数复制一份到函数中,这样在函数中对参数进行修改,将不会影响到实际参数。
- 引用传递(pass by reference):在调用函数时,将实际参数的地址直接传递到函数中,那么在函数中对参数进行修改将影响实际参数。
java中其实还是值传递的,只不过对于对象参数,值的内容是对象的引用
示例:
public class scanner {
String name;
String gender;
static class User extends scanner{
}
public void setName(String name){
this.name = name;
}
public void setGender(String gender){
this.gender = gender;
}
public void pass(User user){
user = new User();
user.setName("change");
user.setGender("Male");
System.out.println("print in pass: "+user.name+" " + user.gender);
}
public static void main(String[] args) {
scanner scan = new scanner();
User user = new User();
scan.setName("static");
scan.setGender("Female");
user.pass(user);
System.out.println("print in main: " + scan.name+" " + scan.gender);
}
}
输出结果:
print in pass , user is User{
name='change', gender='Male'}
print in main , user is User{
name='static', gender='Male'}
3. 方法的重载
- 重载就是在一个类中,有相同的函数名称,但形参不同的函数。
- 方法重载的规则:
- 方法名称必须相同。
- 参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)。
- 方法的返回类型可以相同也可以不相同。
- 仅仅返回类型不同不足以成为方法的重载。
实现理论:
方法名称相同时,编译器会根据调用方法的参数个数,参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错。
public class Hero {
String name;
float hp;
float armor;
int movespeed;
public Hero(String heroName,float heroHP) {
name = heroName;
hp = heroHP;
}
public Hero(String heroName, float heroHP, float heroArmor, int heroMoveSpeed){
name = heroName;
hp = heroHP;
armor = heroArmor;
movespeed = heroMoveSpeed;
}
public static void main(String[] args) {
Hero timo = new Hero("提莫",80);
Hero gailun = new Hero("盖伦",100,20,300);
}
}
4. 命令行传参
一般情况下 我们的main方法是不需要参数传入的 但是如果在工作中需要我们写一些小的应用程序 并且以jar包的方式发给其他人员直接在dos界面使用并且需要输入参数的时候就需要用到main的参数传递。
4.1 方式一:从命令提示符中传值
示例:
public class TestMain {
public static void main(String[] args) {
System.out.println("Hello " + args[0]);
System.out.println("World " + args[1]);
}
}
shift鼠标右键文件夹,进入powershell界面,输入 javac TestMain.java 进行编译,然后运行java TestMain.java:
此时如果输出args.length长度应该为4
4.2 方式二:直接在java代码中进行赋值:
示例
public class TestMain {
public static void main(String[] args) {
args = new String[]{
"a","b","c"};
System.out.println(args.length);
System.out.println(args[0]);
}
}
输出:
3
a
4.3 方式三:通过开发工具传参数:
示例:
public class TestMain {
public static void main(String[] args) {
System.out.println(args[0]);
System.out.println(args[1]);
System.out.println(args[2]);
}
}
传入参数:
输出:
a
c
v
总结:
1.运行Java程序的同时,可以通过输入参数给main函数中的接收参数数组args[],供程序内部使用!即当你在Java命令行后面带上参数,Java虚拟机就直接把它们存放到了main方法中的参数String数组里了。
2.args是Java命令行参数,因为参数可以为多个,所以要用数组来存我们在DOS中执行Java程序的时候使用“java 文件名 args参数”。args这个数组可以接收到这些参数。
5. 可变参数
5.1 定义
可变参数:适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理。
注意:可变参数必须位于最后一项。
使用格式:
修饰符 返回值类型 方法名(数据类型...方法名){
}
- JDK 1.5 开始,Java支持传递同类型的可变参数给一个方法。
- 在方法声明中,在指定参数类型后加一个省略号(…)。
- 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
- 调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中以数组的形式访问可变参数。
5.2 传递单个数据类型
public class qwe {
public static int add(int...n){
int sum=0;
for (int i:n)
{
sum+=i;
}
return sum;
}
public static void main(String[] args) {
int a =add(1,2,3,4,5);
System.out.println(a);
}
}
5.3 传递多个数据类型的方法
public class qwe {
public static int add(String a,double b,int...n){
System.out.println(a);
System.out.println(b);
int sum=0;
for (int i:n)
{
sum+=i;
}
return sum;
}
public static void main(String[] args) {
int a =add("chain",3.14,3,4,5);
System.out.println(a);
}
}
6. 递归
- A 方法调用 B 方法,我们很容易理解!
- 递归就是:A 方法调用 A 方法!就是自己调用自己
- 利用递归可以用简单的程序来解决一些复杂的问题。它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可貌似出解决过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。
- 递归结构包括两个部分:
- 递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。
- 递归体:什么时候需要调用自身方法。
- 递归适合小计算,如果太大量计算容易内存崩溃,死机。
示例:
public class scanner {
public static void main(String[] args) {
System.out.println("请输入想要递归的数字: ");
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
int result= f(a);
System.out.println(result);
}
public static int f(int a){
if (a == 1) {
return 1;
}
else {
return a*f(a-1);
}
}
}
7. 数组
7.1 数组的定义
数组是一个固定长度的,包含了相同类型数据的容器。
7.2 数组的四个基本特点
- 其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
- 其元素必须是相同类型,不允许出现混合类型。
- 数组中的元素可以是任何数据类型,包括基本类型和引用类型。
- 数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。
- 数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,
数组对象本身是在堆中的。
7.3 数组的声明创建
int[] a;
声明了一个数组变量。
[]表示该变量是一个数组
int 表示数组里的每一个元素都是一个整数 a 是变量名
但是,仅仅是这一句声明,不会创建数组
int[] b = new int[5];
//声明的同时,指向一个数组
数组的元素是通过索引访问的,数组索引从0开始
实例:
public static void main(String[] args){
int[] nums; //1.首选声明一哥数组
nums = new int[10]; //2.创建一哥数组
//3.给数组元素中赋值
nums[0] = 1;
nums[1] = 2;
nums[2] = 3;
nums[3] = 4;
nums[4] = 5;
nums[5] = 6;
nums[6] = 7;
nums[7] = 8;
nums[8] = 9;
nums[9] = 10;
//计算所有元素的和
int sum = 0;
//获取数组长度:arrays.length
for (int i = 0; i < nums.length ; i++){
sum = sum + nums[i];
}
System.out.println("总和:"+sum);
}
public class qwe {
private static void sum(int a[]) {
int result = 0;
for (int i = 0; i < a.length; i++) {
result +=a[i];
}
System.out.println(result);
}
public static void main(String[] args) {
int[] a= new int[]{
1,2,3,4,5,6};
sum(a);
}
}
7.4 内存分析
7.5 数组的三种初始化
- 静态初始化
//静态初始化:创建 + 赋值
int[] a = {
1,2,3};
Man[] mans = {
new Man(1,1),new Man(2,2)};
- 动态初始化
//动态初始化:包含默认初始化,未赋值前为0。
int[] a = new int[2];
a[0] = 1;
a[1] = 2;
- 数组的默认初始化
- 数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方法被隐式初始化。
7.6 数组边界
- 下标的合法区间:[0,length-1],越界就会报错
public static void main(String[] args){
int[] a=new int[2]; //a长度为2,下标表示为a[0],a[1].
System.out.println(a[2]);//a[2]以超出设定值
}
ArraylndexOutOfBoundsException:数组下标越界异常!
- 小结
- 数组是相同数据类型(数据类型可以为任意类型)的有序集合
- 数组也是对象。数组元素相当于对象的成员变量
- 数组长度的确定的,不可变的。如果越界,则报:ArrayindexOutofBounds
7.7 数组排序(选择法\冒泡法)
- 选择法排序:
把第一位和其他所有的进行比较,只要比第一位小的,就换到第一个位置来比较完后,第一位就是最小的;然后再从第二位和剩余的其他所有进行比较,只要比第二位小,就换到第二个位置来,比较完后,第二位就是第二小的,以此类推…
示例:
public class qwe {
public static void choose_sorted(int a[]){
for (int i = 0; i <a.length ; i++) {
for (int j = i+1; j < a.length; j++) {
if (a[j] < a[i]) {
int temp;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
for (int i:a) {
System.out.print(i+" ");
}
}
public static void main(String[] args) {
int[] a =new int[]{
11,12,56,23,48,21,15};
choose_sorted(a);
}
}
- 冒泡法排序:
第一步:从第一位开始,把相邻两位进行比较 如果发现前面的比后面的大,就把大的数据交换在后面,循环比较完毕后,最后一位就是最大的;第二步:再来一次,只不过不用比较最后一位.
以此类推
public class qwe {
public static void bubble_sort(int a[]){
for (int i = 0; i <a.length ; i++) {
for (int j = 0; j < a.length-i-1; j++) {
if (a[j+1] < a[j]) {
int temp;
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
for (int i:a) {
System.out.print(i+" ");
}
}
public static void main(String[] args) {
int[] a =new int[]{
11,12,56,23,48,21,15};
bubble_sort(a);
}
}
7.8 二维数组
- 初始化二维数组
int arr[3][4];//这表示定义了一个3行4列的二维数组,并且行优先
有以下几种表示二维数组元素的方法:
int brr [3] [4] ={
{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int crr [3] [4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int err [3][4] = {1,2,3,4,5};
示例:
public class HelloWorld {
public static void main(String[] args) {
//初始化二维数组,
int[][] a = new int[2][3]; //有两个一维数组,每个一维数组的长度是3
a[1][2] = 5; //可以直接访问一维数组,因为已经分配了空间
//只分配了二维数组
int[][] b = new int[2][]; //有两个一维数组,每个一维数组的长度暂未分配
b[0] =new int[3]; //必须事先分配长度,才可以访问
b[0][2] = 5;
//指定内容的同时,分配空间
int[][] c = new int[][]{
{
1,2,4},
{
4,5},
{
6,7,8,9}
};
}
}
练习:
定义一个5X5的二维数组。 然后使用随机数填充该二维数组。找出这个二维数组里,最大的那个值,并打印出其二维坐标.
0-100的 随机整数的获取办法有多种,下面是参考办法之一:
(int) (Math.random() * 100)
Math.random() 会得到一个0-1之间的随机浮点数,然后乘以100,并强转为整型即可。
public class qwe {
public static void find_big(int a[][]) {
int temp=a[0][0];
int x = 0;
int y = 0;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length-1; j++) {
if (temp<a[i][j+1]) {
temp =a[i][j+1];
x=i;
y=j+1;
}
}
}
System.out.println("最大的是:"+temp);
System.out.println("其坐标是" + "[" + x + "]" + "[" + y + "]");
}
public static void main(String[] args) {
int[][] a =new int[5][5];
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length; j++) {
a[i][j]=(int)(Math.random()*100);
System.out.print(a[i][j]+" ");
}
System.out.println();
}
find_big(a);
}
}
运行结果:
7.9 数组的增强for循环
- 一维数组的增强for循环:
public class HelloWorld {
public static void main(String[] args) {
int[] a=new int[]{
1,2,3,4,5,6};
for (int i:a)
{
System.out.println(i);
}
}
}
- 对与二维数组,可以看做一个一维数组的每个元素也是一个数组所以对其的遍历方法应进行增强for循环的嵌套:
public class HelloWorld {
public static void main(String[] args) {
int[][] a=new int[][]{
{
1,2,3,4,5,6},{
7,8,9}};
for (int[] i:a)
{
for (int j: i) {
System.out.println(j);
}
}
}
}
7.10 Array类
Arrays是针对数组的工具类,可以进行 排序,查找,复制填充等功能。大大提高了开发人员的工作效率。
- 数组的工具类java.uti.Arrays
- Arrays 类中的方法都是 static 修饰的静态方法,在使用的时候可以直接使用类名进行调用,而“不用”使用对象来调用(注意:是“不用”而不是“不能”)
7.10.1 数组复制
与使用System.arraycopy进行数组复制类似的, Arrays提供了一个Arrays.copyOfRange
方法进行数组复制。
copyOfRange(int[] original, int from, int to)
// 第一个参数表示源数组
// 第二个参数表示开始位置(取得到)
// 第三个参数表示结束位置(取不到)
import java.util.Arrays;
public class HelloWorld {
public static void main(String[] args) {
int a[] = new int[] {
18, 62, 68, 82, 65, 9 };
int[] b = Arrays.copyOfRange(a, 0, 3);
//复制第0~2位,分别是18,62,68
for (int i = 0; i < b.length; i++) {
System.out.print(b[i] + " ");
}
}
}
7.10.2 转为字符串
如果要打印一个数组的内容,就需要通过for循环来挨个遍历,逐一打印
但是Arrays提供了一个Arrays.toString()
方法,直接把一个数组,转换为字符串,这样方便观察数组的内容
import java.util.Arrays;
public class HelloWorld {
public static void main(String[] args) {
int a[] = new int[] {
18, 62, 68, 82, 65, 9 };
String content = Arrays.toString(a);
System.out.println(content);
}
}
7.10.3 排序
除了前面的选择法排序 和 冒泡法排序,Arrays工具类提供了一个Arrays.sort
方法,只需要一行代码即可完成排序功能。
import java.util.Arrays;
public class HelloWorld {
public static void main(String[] args) {
int a[] = new int[] {
18, 62, 68, 82, 65, 9 };
System.out.println("排序之前 :");
System.out.println(Arrays.toString(a));
Arrays.sort(a);
System.out.println("排序之后:");
System.out.println(Arrays.toString(a));
}
}
7.10.4 搜索
查询元素出现的位置,需要注意的是,使用Arrays.binarySearch
进行查找之前,必须使用sort进行排序,如果数组中有多个相同的元素,查找结果是不确定的.
import java.util.Arrays;
public class HelloWorld {
public static void main(String[] args) {
int a[] = new int[] {
18, 62, 68, 82, 65, 9 };
Arrays.sort(a);
System.out.println(Arrays.toString(a));
//使用binarySearch之前,必须先使用sort进行排序
System.out.println("数字 62出现的位置:"+Arrays.binarySearch(a, 62));
}
}
7.10.5 判断是否相同
利用Arrays.equals()
来比较两个数组内容是否一样.
import java.util.Arrays;
public class HelloWorld {
public static void main(String[] args) {
int a[] = new int[] {
18, 62, 68, 82, 65, 9 };
int b[] = new int[] {
18, 62, 68, 82, 65, 8 };
System.out.println(Arrays.equals(a, b));
}
}
7.10.6 填充
Attays.fill()
方法用于使用同一个值,填充整个数组
import java.util.Arrays;
public class HelloWorld {
public static void main(String[] args) {
int a[] = new int[10];
Arrays.fill(a, 5);
System.out.println(Arrays.toString(a));
}
}
练习:
首先定义一个5X8的二维数组,然后使用随机数填充满。
借助Arrays的方法对二维数组进行排序。
参考思路: 先把二维数组使用System.arraycopy进行数组复制到一个一维数组 然后使用sort进行排序 最后再复制回到二维数组。
import java.util.Arrays;
public class HelloWorld {
public static void main(String[] args) {
int[][] a = new int[5][8];
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
a[i][j]=(int) (Math.random()*100);
System.out.print(a[i][j]+" ");
}
System.out.println();
}
int[] b = new int[a.length*a[0].length];
for (int i = 0; i < a.length ; i++) {
System.arraycopy(a[i],0,b,i*a[i].length,a[i].length);
}
Arrays.sort(b);
for (int i = 0; i <a.length; i++) {
System.arraycopy(b,a[i].length*i,a[i],0,a[i].length);}
for (int[] k :a
) {
System.out.println();
for (int j:k
) {
System.out.print(j+" ");
}
}
}