1 java基础语法

1.1 java概述

  • Java 是由 Sun Microsystems 公司于 1995 年 5 月推出的高级程序设计语言。
  • Java是一门面向对象的编程语言,具有功能强大和简单易用两个特征。

1.1.1、java语言的特性

  • 简单性:Java语言底层采用C++语言实现,相对于C++来说,Java是简单的,在Java语言中程序员不需要再操作复杂的指针(指针的操作是很复杂的),继承方面也是只支持单继承(C++语言是一种半面向对象的编程语言,支持多继承,多继承会导致关系很复杂),在很多方面进行了简化。
  • 健壮性:自动垃圾回收机制(GC机制)、异常处理机制、多种开源api支持等成为java高可用的有利保障。
  • 面向对象:Java中提供了封装、继承、多态等面向对象的机制。
  • 多线程:Java语言支持多个线程同时并发执行,同时也提供了多线程环境下的安全机制。
  • 可移植性/跨平台:可移植性/跨平台表示Java语言只需要编写/编译一次,即可处处运行。既可以支持windows环境,又可以支持linux、ios环境。

1.1.2、Java的三种技术架构

JAVASE:Java Platform Standard Edition,完成桌面应用程序的开发,是其它两者的基础;

JAVAEE:Java Platform Enterprise Edition,开发企业环境下的应用程序,主要针对web程序开发;

JAVAME:Java Platform Micro Edition,开发电子消费产品和嵌入式设备,如手机中的程序;

1.1.3、java应用程序的运行机制

先编译(.class),在解释运行。

1.1.4、java程序开发的三个步骤

  • 编写源程序,java源代码文件。
  • 编译源程序,编译器编译编译成java字节码文件。
  • 运行,java虚拟机(JVM)。

1.1.5、开发java应用的要点

  • 一个源文件中只能有一个public修饰的类,其他类个数不限。
  • 一个源文件有n个类时,编译结果的class文件就有n个。
  • 源文件的名字必须和public修饰的类名相同
  • java语言中单词拼写大小写严格区分。
  • main方法入口
  • 每一句以分号(;)结束

1.2、Java 开发环境配置

1.2.1、JDK、JRE和JVM

JDK:(Java Development Kit)java的开发和运行环境,包含java的开发工具和jre。注意:如果只是在这台机器上运行Java程序,则不需要安装JDK,只需要安装JRE即可。

JRE:(Java Runtime Environment)java程序的运行环境,包含java运行的所需的类库(Java核心类库)+JVM(java虚拟机)。

JVM:(Java Virtual Machine)Java虚拟机。

1.2.2、JDK安装

1)安装JDK---选择jdk、jre安装目录,建议两个都安装在同一个java文件夹中的不同文件夹中

2)安装完JDK后配置环境变量  计算机→属性→高级系统设置→高级→环境变量

3)系统变量→新建 JAVA_HOME 变量 。

变量值填写jdk的安装目录(本人是 C:\Program Files\Java\jdk1.8.0_102)

4)系统变量→寻找 Path 变量→编辑

在变量值最后输入 %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;

或者绝对路径

C:\Program Files\Java\jdk1.8.0_102\bin;C:\Program Files\Java\jdk1.8.0_102\jre\bin;

5)系统变量→新建 CLASSPATH 变量

变量值填写   .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar(注意最前面有一点)

.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;

6)检验是否配置成功 运行cmd 输入 java -version

7)编写一个小程序测试一下

class HelloWorld{

    public static void main(String[] args){

        System.out.println("hello world!");

    }

}

1.2.3、JDK安装jdk历史版本下载

搜索 java archive

或者

Java Archive | Oracle

或者

Java Downloads | Oracle

1.3 基本语法 

1.3.1、标识符

1)概念

自定义的代表一定含义的单词,标识类、方法、变量、参数等。由字母、下划线、数字和美元符号组成,不能以数字开头。

2)命名规范

  • 由字母、下划线、数字和美元符号组成,不能以数字开头,区分大小写,不能是关键字和保留字(goto、const),长度一般不超过15个字符。
  • 见名知意。(看到这个单词就知道它表示什么)
  • 遵循驼峰命名方式。(单词界线更明确)

3)驼峰式命名

类名、接口:单个单词,首字母大写,多个单词,首字母都大写。

方法名、参数名、变量名:单个单词,首字母小写,多个单词,第一单词首字母小写,其他单词首字母大写。

常量名全部大写,单词和单词之间使用“_”衔接。

包名:全部小写

4)注意事项

  • 关键字不能用作标识符
  • 标识符区分大小写

1.3.2、关键字

1)概念

赋予了特殊含义的标识符。

关键字不能用作变量名、方法名、类名、包名和参数等。

2)Java中的关键字

访问控制:private、protected、public、default

类、方法和变量修饰符:abstract、class、extends、final、implements、interface、native、new、static、strictfp、synchronized、transient、volatile

程序控制语句:break、case、continue、default、do、else、for、if、instanceof、return、switch、while

错误处理:assert、catch、finally、throw、throws、try

包相关:import、package

基本类型:boolean、byte、char、double、float、int、long、short

变量引用:super、this、void

保留关键字:goto、const、null

1.3.3、变量

1)字面量

字面量就是数据/数值,例如:1234,true,”abc”,’中’,3.14等。

2)变量

变量是内存当中存储数据最基本的单元,将字面量(数据/数值)放到内存当中,给这块内存空间起一个名字,这就是变量。所以变量就是内存当中的一块空间,这块空间有名字、有类型、有值,这也是变量必须具备的三要素。

3)变量声明

语法格式为:数据类型 变量名; //例如:int i;

4)变量分类

数据类型划分:

  • 基本类型变量:数据的值
  • 引用类型变量:数据的地址

声明的位置划分:局部变量、全局变量

局部变量和全局变量的区别:

1. 默认值

  • 局部没有默认值,使用前必须初始化。
  • 全局有默认值,默认为0,不必须初始化。

2. 声明位置

  • 局部在方法内。
  • 全局在方法外类中。

3.作用位置

  • 局部只能在自己声明的方法里。
  • 全局在整个类中

  • 变量根据声明的位置不同可以分为:局部变量和成员变量。
  • 在方法体当中声明的变量以及方法的每一个参数变量都是局部变量。
  • 在方法体外,类体内声明的变量称为成员变量,成员变量声明时如果使用static关键字修饰的称为静态成员变量(简称静态变量),如果没有static关键字修饰则称为实例成员变量(简称实例变量),如以下代码:
public class VarTest {
    //实例变量(成员变量)
    int x = 20;
    //静态变量(成员变量)
    static int y = 200;
    //方法:int a,int b都是局部变量
    public static void sum(int a, int b){
        //局部变量
        int firstNum = 100;
    }
}
  • 局部变量只在方法体当中有效,方法开始执行的时候局部变量的内存才会被分配,当方法执行结束之后,局部变量的内存就释放了。所以局部变量的生命周期非常短暂。

Java语言支持的变量类型有:

  • 类变量:方法外,类中,用 static 修饰。
  • 实例变量:方法外,类中,不过没有 static 修饰。
  • 局部变量:类的方法(方法体内变量或方法参数)或代码块中的变量。

5)局部变量

  • 局部变量声明在方法、构造方法或者语句块中;
  • 局部变量在方法、构造方法、或者语句块被执行的时候创建,当它们执行完成后,变量将会被销毁;
  • 访问修饰符不能用于局部变量;
  • 局部变量只在声明它的方法、构造方法或者语句块中可见;
  • 局部变量是在栈上分配的。
  • 局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用。

6)实例变量

  • 实例变量声明在一个类中,但在方法、构造方法和语句块之外;
  • 当一个对象被实例化之后,每个实例变量的值就跟着确定;
  • 实例变量在对象创建的时候创建,在对象被销毁的时候销毁;
  • 实例变量的值应该至少被一个方法、构造方法或者语句块引用,使得外部能够通过这些方式获取实例变量信息;
  • 实例变量可以声明在使用前或者使用后;
  • 访问修饰符可以修饰实例变量;
  • 实例变量对于类中的方法、构造方法或者语句块是可见的。一般情况下应该把实例变量设为私有。通过使用访问修饰符可以使实例变量对子类可见;
  • 实例变量具有默认值。数值型变量的默认值是0,布尔型变量的默认值是false,引用类型变量的默认值是null。变量的值可以在声明时指定,也可以在构造方法中指定;
  • 实例变量可以直接通过变量名访问。但在静态方法以及其他类中,就应该使用完全限定名:ObejectReference.VariableName。

7)类变量(静态变量)

  • 类变量也称为静态变量,在类中以 static 关键字声明,但必须在方法之外。
  • 无论一个类创建了多少个对象,类只拥有类变量的一份拷贝。
  • 静态变量除了被声明为常量外很少使用,静态变量是指声明为 public/private,final 和 static 类型的变量。静态变量初始化后不可改变。
  • 静态变量储存在静态存储区。经常被声明为常量,很少单独使用 static 声明变量。
  • 静态变量在第一次被访问时创建,在程序结束时销毁。
  • 与实例变量具有相似的可见性。但为了对类的使用者可见,大多数静态变量声明为 public 类型。
  • 默认值和实例变量相似。数值型变量默认值是 0,布尔型默认值是 false,引用类型默认值是 null。变量的值可以在声明的时候指定,也可以在构造方法中指定。此外,静态变量还可以在静态语句块中初始化。
  • 静态变量可以通过:ClassName.VariableName的方式访问。
  • 类变量被声明为 public static final 类型时,类变量名称一般建议使用大写字母。如果静态变量不是 public 和 final 类型,其命名方式与实例变量以及局部变量的命名方式一致。

1.3.4、Java数据类型

1)基本数据类型

数值型

byte 1字节 8位 -128~127

short 2字节 16位 -32768~32767

int 4字节 32位 -2^31~2^31-1

long 8字节 64位 2^63~2^63-1

浮点类型

float 4字节 32位

double 8字节 64位

字符型

char 2字节 16位 0~65535

布尔型

boolean true false

基本数据类型之间的转换

自动类型转换:

范围小→范围大 byte→short→int→long→float→double;

char→int→long→float→double

强制类型转换:范围大→范围小,需要加强制转换符

byte:

  • byte 数据类型是8位、有符号的,以二进制补码表示的整数;
  • 最小值是 -128(-2^7);
  • 最大值是 127(2^7-1);
  • 默认值是 0;

short:

  • short 数据类型是 16 位、有符号的以二进制补码表示的整数
  • 最小值是 -32768(-2^15);
  • 最大值是 32767(2^15 - 1);
  • 默认值是 0;

int:

  • int 数据类型是32位、有符号的以二进制补码表示的整数;
  • 最小值是 -2,147,483,648(-2^31);
  • 最大值是 2,147,483,647(2^31 - 1);
  • 一般的整型变量默认为 int 类型;
  • 默认值是 0 ;

long:

  • long 数据类型是 64 位、有符号的以二进制补码表示的整数;
  • 最小值是 -9,223,372,036,854,775,808(-2^63);
  • 最大值是 9,223,372,036,854,775,807(2^63 -1);
  • 默认值是 0L;

float:

  • float 数据类型是单精度、32位;
  • float 在储存大型浮点数组的时候可节省内存空间;
  • 默认值是 0.0f;

double

  • double 数据类型是双精度、64 位
  • 浮点数的默认类型为 double 类型;
  • 默认值是 0.0d;

boolean

  • 只有两个取值:true 和 false
  • 默认值是 false

char:

  • char 类型是一个单一的 16 位 Unicode 字符;
  • 最小值是 \u0000(十进制等效值为 0);
  • 最大值是 \uffff(即为 65535);

2)引用类型

字符串 String、 类 class 、枚举 enum、接口interface

1.3.5、Java 常量

Java 中使用 final 关键字来修饰常量,声明方式和变量类似。

final double PI = 3.1415927;

1.3.6、运算符

算术运算符:+ - * / % ++ --

赋值运算符:= += -= *= /= %= >= &= ^= |=

关系运算符:> < >=

逻辑运算符:! & | ^ && ||

位运算符:

&:按位与。

|:按位或。

~:按位非。

^:按位异或。

>>:右位移运算符。

三目运算符(条件运算符):x ? y : z

1)对两个变量的数据进行互换

a = a + b;
b = a - b;
a = a - b;

a = a ^ b;
b = a ^ b;
a = a ^ b;

2)注意

& 和 &&区别

&:无论左边结果是什么,右边都参与运算。

&&:短路与,如果左边为false,那么右边不参数与运算。

| 和|| 区别

|:两边都运算。

||:短路或,如果左边为true,那么右边不参与运算。

前缀自增自减法(++a,--a):先进行自增或者自减运算,再进行表达式运算。

后缀自增自减法(a++,a--):先进行表达式运算,再进行自增或者自减运算。

int a = 5;//定义一个变量;
int b = 5;
int x = 2*++a;
int y = 2*b++;
System.out.println("自增运算符前缀运算后a="+a+",x="+x);
System.out.println("自增运算符后缀运算后b="+b+",y="+y);

3)Java运算符优先级

优先级

运算符

结合性

1

( ) [ ]  .

从左到右

2

!  ~  ++  --

从右到左

3

*  /  %

从左到右

4

+  -

从左到右

5

>  >>>

从左到右

6

<    >=  instanceof

从左到右

7

==  !=

从左到右

8

&

从左到右

9

^

从左到右

10

|

从左到右

11

&&

从左到右

12

||

从左到右

13

? :

从左到右

14

=  +=  -=  *=  /=  %=  &=  |=  ^=  ~=  >=  >>>=

从右到左

1.3.7、二进制

计算机中的数据都以二进制数据保存。

计算机信息的存储单位:

位(bit):是计算机存储处理信息的最基本的单位

字节(byte):一个字节有8个位组成。

1.3.8、转义字符

\n 换行 \r 回车 \t 水平制表 ' 单引号 " 双引号 \斜杠

1.4、Java流程控制语句

程序三种执行顺序:顺序结构、选择(分支)结构、循环结构。

1.4.1、选择结构

1)if语句

//if语句
if(){    
}

//if...else...
if(){    
}else{
}

//if...else if...else
if(){    
}else if(){
}else{
}

//if嵌套
if(){
    if(){        
    }else{        
    }
} 

2)switch语句

switch(表达式expr){
    case const1:
        statement1;
        break;
    ...
    case constN:
        statementN;
        break;
    [default:
        statement_dafault;
        break;]
}

注意:

  1. 表达式必须是int、byte、char、short、enmu、String类型
  2. constN必须是常量或者final变量,不能是范围
  3. 所有的case语句的值不能相同,否则编译会报错
  4. default可要可不要
  5. break用来执行完一个分支后使程序跳出switch语句块,否则会执行下面的语句。

1.4.2、循环结构

Java中有三种主要的循环结构:

  • while 循环
  • do…while 循环
  • for 循环

1)while语句

while(判断条件){

   循环体;

}

2)do...while语句

do{
    循环体;
}while(判断条件);

3)for语句

for(初始化; 布尔表达式; 迭代更新){
    循环体;
} 

4)增强for

for(声明语句 : 表达式){
 循环体;
}

声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。

表达式:表达式是要访问的数组名,或者是返回值为数组的方法。

5)break 关键字

break 主要用在循环语句或者 switch 语句中,用来跳出整个语句块。

break 跳出最里层的循环,并且继续执行该循环下面的语句。

public class BreakTest {
    public static void main(String[] args) {
        int [] numbers = {10, 20, 30, 40, 50}; 
        for(int x : numbers ) {
            // x 等于 30 时跳出循环
            if( x == 30 ) {
                break;
            }
            System.out.print( x );
            System.out.print("\n");
        }
    }
}

//运行结果如下:
10
20

6)continue 关键字

continue 适用于任何循环控制结构中。作用是让程序立刻跳转到下一次循环的迭代。

在 for 循环中,continue 语句使程序立即跳转到迭代更新语句。

在 while 或者 do…while 循环中,程序立即跳转到布尔表达式的判断语句。

public class ContinueTest {
    public static void main(String[] args) {
        int [] numbers = {10, 20, 30, 40, 50};
        for(int x : numbers ) {
            // x 等于 30 时跳出循环
            if( x == 30 ) {
                continue;
            }
            System.out.print( x );
            System.out.print("\n");
        }
    }
}

continue:只作用于循环结构,继续循环用的

1.5、Java方法

1.5.1、什么是方法

  • Java方法是语句的集合,它们在一起执行一个功能。
  • 方法是解决一类问题的步骤的有序组合
  • 方法包含于类或对象中
  • 方法在程序中被创建,在其他地方被引用

1.5.2、方法的优点

  • 使程序变得更简短而清晰。
  • 有利于程序维护。
  • 可以提高程序开发的效率。
  • 提高了代码的重用性。

1.5.3、方法的定义

[修饰符] 返回值类型 方法名([形式参数列表]){
    方法体;
    [return 返回值;]
}

1.5.4、方法的重载

方法重载(overload)是指在一个类中定义多个方法名相同,参数列表不同的方法。

参数列表不同:参数个数、参数顺序或者参数类型其中一项或多项不同。

在一个类中,方法名字相同,参数类型不同。

参数类型不同:个数、数据类型、顺序。

注意:

  • 重载和返回值类型,修饰符没有任何关系。
  • 参数变量名修改也不能够称为重载

1.5.5、递归方法

1)什么叫递归

递归函数就是直接或间接调用自身的函数,也就是自身调用自己。

2)一般什么时候使用递归?

递归是常用的编程技术,其基本思想就是“自己调用自己”,一个使用递归技术的方法即是直接或间接的调用自身的方法。递归方法实际上体现了“以此类推”、“用同样的步骤重复”这样的思想。

还有些数据结构如二叉树,结构本身固有递归特性;此外,有一类问题,其本身没有明显的递归结构,但用递归程序求解比其他方法更容易编写程序。

注意事项:

  • 有能够跳出循环的控制语句,否则会发生栈内存溢出。
  • 递归次数不能太多,否则也会发生栈内存溢出。
  • 构造方法,禁止递归

汉罗塔问题,求阶乘,求1-100累加和。八皇后问题,迷宫问题...

3)经典递归算法

 1、用代码实现递归阶乘的结果:n! = n * (n-1) * (n-2) * ...* 1(n>0)

/**
 * @author cz
 */
public class DiGui {
    /**方法一*/
    static int result=1;
    public static int getFactorial(int a){
        if(a>0){
            result=result*a;
            getFactorial(--a);
        }
        return result;
    }

    public static void main(String[] args) {
        int result = getFactorialTest(4);
        System.out.println(result);

    }
    /**方法二*/
    public static int getFactorialTest(int b){
        if(b>0){
            int number = b*getFactorialTest(--b);
            return number;
        }else if(b==0){
            return 1;
        }else{
            return -1;
        }
    }
    
    /**方法三*/
    public static Integer recursionMulity(Integer n){
        if(n==1){
            return 1;
        }
        return n*recursionMulity(n-1);
    }
}

2、判定一系列字符串中是否有相同的内容

public class Crf{
    public static void main(String[] args) {
        String[] a = {"a1","a2","a3","b3","c","b","33","33"};
        fun(0, a);
    }
    
    public static void fun(int n,String[] a){
         if(n==a.length){
            return;
        }
    for(int i = n; i < a.length-1; i++){
            System.out.println(n+"    "+(i+1));
            if(a[n].equals(a[i+1])){
            System.out.println("存在相同字符");    
            System.out.println(a[n]);    
            }
        }
        n++;
        fun(n,a);
    }
}

3、兔子数列(斐波那契数列)

假设一对刚出生的小兔子一个月后就能长成大兔子,再过一个月就能生下一对小兔子,并且此后每个月都生一对小兔子,如果兔子不死的话,请问每个月兔子的总数是多少。

第一个月 1小 1

第二个月 1中 1

第三个月 1大1小 1+1=2

第四个月 1大1中1小 1+1+1=3

第五个月 2大1中2小 2+1+2=5

第六个月 3大2中3小 3+2+3=8

第七个月 5大3中5小 5+3+5=13

第八个月 8大5中8小 8+5+8=21

第九个月 13大8中13小 13+8+13=34

public static void main(String[] args) {
    int i = 1;
    for(i=1;i<=12;i++){
        System.out.println("兔子第"+i+"个月的总数为:"+f(i));
    }
}

public static int f(int x) {
    if (x == 1 || x == 2) {
        return 1;
    } else {
        //当前月的兔子的个数等于前两个月兔子的相加
        return f(x - 1) + f(x - 2);
    }
}

4、猴子吃桃子问题:

猴子第一天摘下若干个桃子,当即吃了快一半,还不过瘾,又多吃了一个。第二天又将仅剩下的桃子吃掉了一半,又多吃了一个。以后每天都吃了前一天剩下的一半多一个。到第十天,只剩下一个桃子。试求第一天共摘了多少桃子?

public static int getPeach(int days) {
    //第十天剩1个桃子
  if (days == 10) {
    return 1;
  }
    //前一天的桃子=当天桃子(getPeach方法)+1*2
  return (getPeach(days+1) + 1) * 2;
}

4)递归的小结

  1. 一个递归的方法每次用不同的参数值反复调用自身,
  2. 某个参数值时递归的方法返回,而不再调用自身,这种称为基值情况,
  3. 一个递归的方法必须存在一个或多个基值,
  4. 任何可以用递归完成的操作都可以用一个栈来实现,
  5. 递归的方法可能效率低,如果是这样的话,有时可以用一个简单循环或者是一个基于栈的方法来代替。

1.5.6、可变参数

JDK 1.5 开始,Java支持在方法参数列表中传递同类型的可变参数。

可变参数语法: paramType... paramName

//可变参数
修饰符 返回值类型 方法名(参数类型... 参数名){}

注意事项:

一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。

1.5.7、return关键字

  • 将数据返回给调用者,除了void外,return后必须跟着返回值,只能返回一个。
  • 终止方法的执行,返回数据类型必须是void,return后不能添加数据。
  • 当return结束方法的时候,要让其后面的代码有可能被执行到。
  • 一个方法里可以有多个return,在void里不能有返回值,其他的必须有返回值。

1.5.8、回调函数

class A{
    private B b;
    public void aMethod(){
        b.bMethod();
    }
    public void callback(){
        //回调逻辑
    }
}
class B{
    private A a;
    public void bMethod(){
        //b方法执行逻辑
        a.callback{}
    }
}

1.6、Java数组

1.6.1、数组的定义

数组:用于存储同一类型数据的一个容器。

1.6.2、数组初始化

元素类型[] 变量名 = new 元素类型[元素的个数];

元素类型[] 变量名 = {元素1,元素2...};

元素类型[] 变量名 = new 元素类型[]{元素1,元素2...};

1.6.3、数组的遍历

//for-each循环
for(type element: array){
    System.out.println(element);
}
//for循环
for(int i=0;i<array.size;i++>){
    System.out.println(array[i]);
}

1.6.4、数组的应用

1.6.4.1、数组的遍历

/*数组的遍历,循环,根据每个数组下标依次取出每个元素*/
int[] arr={10,8,21,13,66,22,91,68};
for(int i=0;i<arr.length;i++){
    System.out.println(arr[i]);
}

1.6.4.2、求数组最大值

/*思路一:先取出一个元素作为最大值,然后遍历数组,和数组的每一个元素比较,比最大值大就交换*/
int[] arr={10,8,21,13,66,22,91,68};
int max=arr[0];
for(int i=0;i<arr.length;i++){
    if(arr[i]>max){
        /*
        交换逻辑:
        第一种方法: int a,b  a=a+b; b=a-b; a=a-b;
                             a=a^b; b=a^b; a=a^b;
        第二种方法: int a,b,temp  temp=a; a=b; b=temp;
        */
        arr[i]=arr[i]+max;
        max=arr[i]-max;
        arr[i]=arr[i]-max;
    }
    System.out.println("数组最大值:"+max);
}

/*思路二:先取出第一个元素的下标作为最大值下标,然后遍历数组,和数组的每一个元素比较,比最大值大就交换下标*/
int[] arr={10,8,21,13,66,22,91,68};
int max=0;
for(int i=0;i<arr.length;i++){
    if(arr[i]>arr[max]){
       i=i+max;
       max=i-max;
       i=i-max;
    }
    System.out.println("数组最大值:"+arr[max]);
}

1.6.4.3、找出数组中的某一个元素

//遍历数组,如果相等打印输出并记录下标。
int[] arr={10,8,21,13,66,22,91,68};
int temp=91,index=-1;
for(int i=0;i<arr.length;i++){
    if(arr[i]==temp){
        System.out.println("元素:"+temp+"在数组下标第:"+i+"位置");
        index=i;
    }
}
if(index==-1){
    System.out.println("元素:"+temp+"不在数组中!");
}

1.6.4.4、打印乘法口诀表

/*  
1*1=1
2*1=2 2*2=4
3*1=3 3*2=6 3*3=9
...

1*1口诀表:第一行(i=1),有1列(j=1) 1*1=1  
2*2口诀表:第一行(i=1),有2列(j=1) 1*1=1  
          第二行(i=2),有2列(j=1) 2*1=2  (j=2)2*2=4   
n*n口诀表:第一行(i=1),有1列(j=1) 1*1=1  
          第二行(i=2),有2列(j=1) 2*1=2... 
          第三行(i=3),有3列(j=1) 3*1=3...   
          第i行(i=n), 有j列(j=1)  i*1=i...
...

n*n口诀表:第i行,第j列  i*j;最大行数 i=n,每一行列数 j<=i
*/
public void printMulTab(int n){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=i;j++){
            System.out.print(i+"*"+j+"="+i*j+"\t");
        }
        System.out.print("\n");    
    }
}

1.6.4.5、数组动态扩容问题

//数组动态扩容
//指定初始大小
int[] arr=new int[0];
int[] newArr=new int[newLen];

//第一种方法:遍历数组,把每一项元素放入新生成的数组中
for(int i=0;i<arr.length;i++){
    newArr[i]=arr[i];
}

//第二种方法:调用System.arraycopy方法
//将array数组从0位置至array.length位置,复制到newArray数组0位置到array.length位置。
System.arraycopy(arr,0,newArr,0,arr.length);

1.6.4.6、数组排序

1)冒泡排序

//冒泡排序  相邻两个数比较,大的数往后移,一轮比较下来,最后一个数(arr.length-1位置)就是最大的数,
//然后前(arr.length-1)个数再次比较出最大的数,放到(arr.length-2)的位置。
//依次比较下来,每轮比出剩下的数中最大的数,移动到剩余数组最后面。
//n轮之后,剩下的数arr.length-n==1的时候,排序完成。
int[] arr={10,8,21,13,66,22,91,68};
//循环几轮
for(int i=0;i<arr.length-1;i++){
    //每一轮循环
    for(int j=0;j<arr.length-1-i;j++){
        //前一个数比后一个数大,交换位置
        if(arr[j]>arr[j+1]){
            arr[j]=arr[j+1]+arr[j];
            arr[j+1]=arr[j]-arr[j+1];
            arr[j]=arr[j]-arr[j+1];
        }
    }
    
}

2)选择排序

//选择排序
//从数组n个元素中,选出一条最大或者最小值,记录他的下标,并把他和数组最前面或者最后面元素交换;
//每轮比较下来,剩下的元素减1,确定一条最大或者最小值元素。
//n轮比较完,当剩下的元素只有一个的时候,排序完成
int[] arr={10,8,21,13,66,22,91,68};
//循环几轮
for(int i=0;i<arr.length-1;i++){
    //记录最大值下标
    int max=0;
    //每一轮最后一个元素的下标
    int last=arr.length-i-1;
    //每一轮循环,记录最大值下标
    for(int j=0;j<arr.length-i;j++){
        if(arr[j]>arr[max]){
            max=j;
        }
    }
    //一轮比较完,把最大值和最后元素交换位置
    if(last!=max){
        arr[max]=arr[last]+arr[max];
        arr[last]=arr[max]-arr[last];
        arr[max]=arr[max]-arr[last];
    } 
}



int[] arr={10,8,21,13,66,22,91,68};
//循环几轮
for(int i=0;i<arr.length-1;i++){
    //剩余元素的第一个数下标
    int temp=i;
    //每一轮循环,记录最小值下标
    for(int j=i;j<arr.length;j++){
        if(arr[j]<arr[temp]){
            temp=j;
        }
    }
    //一轮比较完,把最小值和最前面的元素交换位置
    if(temp!=i){
        arr[temp]=arr[i]+arr[temp];
        arr[i]=arr[temp]-arr[i];
        arr[temp]=arr[temp]-arr[i];
    } 
}

3)插入排序

//插入排序
//数组从左到右依次取出元素,和他左边的元素比较,如果元素比他大就右移一位,直到找到比他小的那个数;
//此时,比他小的那个数下标+1就是这个元素要插入的位置。
//依次论推,每次都能找到一个元素在这个数组的正确排序,并放入。n-1次后就能排好n个元素的数组。
int[] arr={10,8,21,13,66,22,91,68};

//从下标0开始,依次取出数组中的一个元素作为要插入的数
for(int i=1;i<arr.length;i++){
    //要插入的数
    int target=arr[i];
    //数组左边是已插入的元素(有排序),和左边的元素依次比较,j左边元素的下标
    int j=i-1;
    //如果数组小下标方向还有元素,且当前小下标元素大于目标元素(要插入的元素),当前小下标元素右移一位
    while(j>=0 && arr[j]>target){
        arr[j+1]=arr[j];
        j--;
    }
    //找到比目标元素小的元素,将目标元素放到这个元素后一位
    arr[j+1]=target;
}



for(int i=1;i<arr.length;i++){
    //要插入的数
    int target=arr[i];
    //数组左边是已插入的元素(有排序),和左边的元素依次比较,j左边元素的下标
    
    //如果数组小下标方向还有元素,且当前小下标元素大于目标元素(要插入的元素),当前小下标元素右移一位
    for(int j=i-1;j>=0 && arr[j]>target;j--){
        arr[j+1]=arr[j];
    }
    //找到比目标元素小的元素,将目标元素放到这个元素后一位
    arr[j+1]=target;
}

1.6.4.7、打印杨辉三角

/*
打印杨辉三角
      1
    1   1
   1  2  1
 1  3   3  1 
1  4  6  4  1

第一行   空格 5-1  数据 1
第二行   空格 5-2  数据 1   1
第三行   空格 5-3  数据 1  1+1=2  1
第四行   空格 5-4  数据 1  1+2=3  2+1=3  1
第五行   空格 5-4  数据 1  1+3=4  3+3=6  3+1=4  1

第一行  1
第二行  1 1
第n行   第一个数1,最后一个数1,空格最大行数n-当前行数i,中间数(第i行第j列)上一行i-1,第j-1列数+第j列数
递归方法
*/


1.6.4.8、找出数组中的某一个元素

二分查找法。前提:数组中的元素要有序。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值