【JavaSE 一】Java语言基础

本文详细介绍了Java语言的基础语法,包括注释、数据类型、变量转换、运算符、数字与字符串处理、字符串缓冲区操作,以及输入输出、控制流程、数组和循环等核心概念。通过实例展示了如何计算自然对数、质数、字符串操作、数组排序等,同时探讨了输入输出的格式化、控制流和循环结构,以及数组和字符串的使用。此外,还提供了练习题,涵盖字符串数组排序、字符串转换、随机字符串生成等多个方面。
摘要由CSDN通过智能技术生成

文章目录

一、语言基础语法

1)注释

单行注释

​ 使用//单行注释

//单行注释

多行注释

​ 使用/**/多行注释

/*
这里是多行注释
这里是多行注释
这里是多行注释
*/

文档注释

​ 使用/****/文档注释

/***
* 这里时文档注释
* author:作者
*
*/

​ 使用这个命令 javaDoc -encoding UTF-8 -charset UTF-8 HelloWorld.java 去生成Java的api文档

2)数据类型

基本数据类型

类型默认值长度数值范围
byte08-128~127
short016-32768~32767
int032-2147483648 ~ 2147483647
long0L64-9223372036854775808 ~ 9223372036854775807
float0.0F323.4E-38~3.4E+38
double0.0D641.7E-308~1.7E+308
booleanfalse1true和false
char‘\u0000’16‘\u0000’ ~ ‘\uffff’

数据类型的扩展

  1. 整型
int decVal = 26;//十进制形式
int hexVal = 0x1a;//十六进制形式
int binVal = 0b11010;//二进制形式
int octVal = 010;//八进制形式
  1. 浮点型

    不能用==来比较大小,因为他们是不精确的,所以不能用于银行数据

double d1 = 123.4double d2 = 1.234e2;
float f1  = 123.4f;
  1. 字符型
char c1 = "A";//输出字符A
char c2 = 65;//输出字符A
char c = '\u0065';//输出字符e
  1. 数字中可以使用下划线

​ 作用是分隔数字文字中的数字组,这可以提高代码的可读性

例如:

long creditCardNumber = 1234_5678_9012_3456L;
long socialSecurityNumber = 999_99_9999L;
float pi =  3.14_15F;
long hexBytes = 0xFF_EC_DE_5E;
long hexWords = 0xCAFE_BABE;
long maxLong = 0x7fff_ffff_ffff_ffffL;
byte nybbles = 0b0010_0101;
long bytes = 0b11010010_01101001_10010100_10010010;

以下是非法例子

float pi1 = 3_.1415F; //无效:不能在小数点附近放置下划线
float pi2 = 3._1415F; //无效:不能在小数点附近放置下划线 
socialSecurityNumber1 = 999_99_9999_L; //无效:不能在 L 后缀之前加上下划线 long 
int x2 = 52_; //无效:不能放下划线在文字的末尾
int x4 = 0_x52; //无效:不能下划线在 0x 基数前缀
int x5 = 0x_52; //无效:不能在数字开头放置下划线
int x7 = 0x52_;//无效:不能在数字末尾添加下划线

变量的类型转换

​ 不同类型之间的数据可以互相转换,但是要满足一定的规则

​ byte,short char->int->long->float->double

​ 转换规则按照长度大小,从小到大自动转,从大到小强制转

​ 虽然short和char都是16位的,长度是一样的但是彼此之间,依然需要进行强制转换(避免内存溢出)

​ 操作大数时注意内存溢出问题

int money = 1_000_000_000;//十亿
int year = 20;
int total = money*year;
System.out.println(total);//输出-1474836480,不期望的结果
double total2 = money*year;
System.out.println(total2);//输出-1474836480,不期望的结果
double total3 = (long)money*year;
System.out.println(total3);//输出2.0E10,正确的结果

3)变量与常量

变量分类及作用域

​ 分类

​ 基本数据类型:数值(整数,浮点,字符),布尔

​ 引用数据类型:类,接口,数组

  • 实例变量(非静态字段):
    对象将它们各自的状态存储在“非静态字段”中,即没有static关键字声明的字段。非静态字段也称为实例变量,因为它们的值对于类的每个实例(换句话说,对于每个对象)都是唯一的;作用域整个类
  • 类变量(静态字段):
    使用static修饰符声明的任何字段;这告诉编译器存在这个变量的一个副本,不管这个类被实例化了多少次,都有共同的一个字段。此外,可以添加关键字final来表示变量值永远不会改变。作用域整个类
  • 局部变量
    方法通常会将其临时状态存储在局部变量中。声明局部变量的语法类似于声明字段(例如,int count = 0;)。局部变量不需修饰符;局部变量仅对声明它们的方法可见;其他类无法访问它们。作用域整个块
  • 参数:
    回想一下,该main方法public static void main(String[] args). 这里,args变量是这个方法的参数。要记住的重要一点是,参数总是被归类为“变量”而不是“字段”。作用域方法内

局部变量没有初始值,如果声明时没有初始化,必须在使用前赋值

变量和字段区别

​ 如果我们谈论“一般的字段”(不包括局部变量和参数),我们可能会简单地说“字段”。如果讨论适用于“以上所有”,我们可以简单地说“变量”。如果上下文需要区分,我们将酌情使用特定术语(静态字段、局部变量等)

变量的命名

  1. 变量名区分大小写
  2. 以字母、美元符号“ $”或下划线字符“ _”开头,然而惯例始终以字母开头,而不是“ $”或“ _
  3. 不允许使用空格
  4. 建议请使用完整的单词而不是隐晦的缩写
  5. 您选择的名称不能是 关键字或保留字
  6. 如果它包含多个单词,则将每个后续单词的第一个字母大写
  7. 如果您的变量存储一个常量值,则约定会略有变化,将每个字母大写并用下划线分隔后续单词
  8. 中文可以用来命名,但是别这么干

常量表示

当一个变量被final修饰的时候,该变量只有一次赋值的机会

final static double PI = 3.14;

4)运算符

算数运算符

​ +,-,*,/,%,++,–

​ 重点关注:

​ b = a++,++在后是后++,意思是赋值完成后再++,b=a

​ b = ++a,++在前是前++,意思是赋值完成前就已经++完成,b=a+1

​ 做除法时可能会产生小数,必须将其中一个强制类型转换为浮点,不然得不到想要的结果

赋值运算符

​ =,+=,-=,*=,/=

​ a+=3,等价于a=a+3,其他类似

关系运算符

​ <,>,>=,<=,==,!=,instenceof(对象使用)

逻辑运算符

​ &&,||,!

​ 值得注意的是“与’'的时候有一个短路情况

​ (条件表达式1 && 条件表达式2),在条件表达式1为false时,就不会再判断条件表达式2,结果直接输出false

​ 还有一种非短路的与或,使用单个&,|

位运算符

​ &,|,^,~,>>,<<,>>>(了解)

​ 在很多算法里面会用到位运算得到精巧的计算,因为位运算和底层打交道效率非常的高

​ 例如计算2^3的时候,用位运算非常快,只需左移两次就可以

左移时,原数据乘以2;右移时,原数据除以2

条件运算符

​ 条件?语句1:语句2

​ 条件为真时执行语句1,为假时执行语句2

5)数字与字符串

装箱拆箱

​ 封装类:所有的基本类型,都有对应的类类型,比如int对应的类是Integer,这种类就叫做封装类

​ Number类:数字封装类有Byte,Short,Integer,Long,Float,Double,这些类都是抽象类Number的子类

​ 基本类型转封装类,Integer it = new Integer(5);

​ 封装类转基本类型,int i = it.intValue();

​ 自动装箱,不需要调用构造方法,通过=符号自动把基本类型转换为类类型就叫装箱,Integer it = 5;

​ 自动拆箱,不需要调用Integer的intValue方法,通过=就自动转换成int类型,就叫拆箱,int i = it;

字符串转换

​ 数字转字符串:

​ 方法1: 使用String类的静态方法valueOf,String str = String.valueOf(5)

valueOf的参数可以是很多基本类型,也可以是字符数组

​ 方法2: 先把基本类型装箱为对象,然后调用对象的toString,String str = it.toString()

​ 字符串转数字:

​ 调用Integer的静态方法parseInt,int i= Integer.parseInt(str)

数学方法

​ 四舍五入:Math.round(0.45)

​ 随机浮点数(0-1,取不到1):Math.random()

​ 随机整数(0-10,取不到10):(int)( Math.random()*10)

​ 开方:Math.sqrt(9)

​ 次方(2的4次方):Math.pow(2,4)

​ 常数π :Math.PI

​ 自然常数:Math.E

字符

char对应的封装类

char c1 = 'a';
Character c = c1; //自动装箱
c1 = c;//自动拆箱

Character常见方法

System.out.println(Character.isLetter('a'));//判断是否为字母
System.out.println(Character.isDigit('a')); //判断是否为数字
System.out.println(Character.isWhitespace(' ')); //是否是空白
System.out.println(Character.isUpperCase('a')); //是否是大写
System.out.println(Character.isLowerCase('a')); //是否是小写
         
System.out.println(Character.toUpperCase('a')); //转换为大写
System.out.println(Character.toLowerCase('A')); //转换为小写
 
String a = 'a'; //不能够直接把一个字符转换成字符串
String a2 = Character.toString('a'); //转换为字符串

常见转义字符

\t是制表符,代表让其后面的字符对齐到下一个制表位,不仅仅代表光标后移8个字符(idea控制台移动4个字符,可以设置为8个)

System.out.println("换行:\n");
System.out.println("制表符:\t");
System.out.println("退格:\b");
System.out.println("回车:\r");
System.out.println("反斜杠:\\");
System.out.println("单引号:\'");
System.out.println("双引号:\"");

字符串

创建字符串

​ 字符串即字符的组合,在Java中,字符串是一个类,所以我们见到的字符串都是对象

​ 常见创建字符串手段:

char[] c1 = new char[]{'我','是','中','国','人'};
String str = "你好";   //每当有一个字面值出现的时候,虚拟机就会创建一个字符串
String str1 = new String("我是new出来的");   //调用String的构造方法创建一个字符串对象
String str2 = new String(c1);   //调用String的构造方法创建一个字符串对象
String str3 = str + str1;   //通过+加号进行字符串拼接也会创建新的字符串对象
System.out.format("%s,%s,%s,%s",str,str1,str2,str3);

String 被修饰为final,所以是不能被继承的

一旦创建好一个字符串,里面的内容永远不能改变,String 的表现就像是一个常量

length方法返回当前字符串的长度,可以有长度为0的字符串,即空字符串

操做字符串

​ 获取指定位置字符:charAt(int index),返回一个字符

​ 获取对应的字符数组:toCharArray(),返回一个字符数组

​ 截取子字符串:substring(3,5),截取3-4位置的字符,返回一个字符串

​ 根据分隔符进行分隔:split(“,”),返回一个字符串数组

​ 去掉首尾空格:trim(),返回一个字符串

​ 全部变成小写:toLowerCase ,返回一个字符串

​ 全部变成大写:toUpperCase ,返回一个字符串

​ 判断字符或者子字符串第一次出现的位置; indexOf (),返回一个整型

​ 判断字符或者子字符串最后一次出现的位置; lastIndexOf (),返回一个整型

​ 判断字符或者子字符串在指定位置(5)之后第一次出现的位置; indexOf (“,”,5),返回一个整型

​ 判断是否包含指定字符串,contains(),返回布尔类型

​ 替换所有指定字符串,replaceAll(),返回一个字符串

​ 替换第一个指定字符串,replaceFirst(),返回一个字符串

比较字符串

是否是同一个对象

String str1 = "hello";
String str2 = new String(str1);
//==用于判断是否为同一个字符串对象
System.out.println( str1  ==  str2);//结果为false

/***
 * 一般说来,编译器每碰到一个字符串的字面值,就会创建一个新的对象
 * 所以str1创建了一个新的字符串"hello"
 * 但是创建str3时,编译器发现已经存在现成的"hello",那么就直接拿来使用,而没有进行重复创建
 */
String str3 = "hello";
System.out.println( str1  ==  str3);//结果为ture

内容是否相同

​ 使用equals进行字符串内容的比较,必须大小写一致,equalsIgnoreCase,忽略大小写判断内容是否一致

是否以子字符串开始或者结束

​ str1.startsWith(str2) //是否以str2开始,str1.endsWith(str2) //是否以str2结束

Stringbuffer

​ StringBuffer是可变长的字符串

​ 常用方法:append()追加,delete ()删除,insert() 插入,reverse() 反转

​ StringBuffer维护了一个长度16的字符数组。这个字符数组,留有冗余长度比如说new StringBuffer(“hello”),其内部的字符数组的长度是21,而不是5,这样调用插入和追加,在现成的数组的基础上就可以完成了。如果追加的长度超过了21,就会分配一个新的数组,长度比原来多一些,把原来的数据复制到新的数组中,看上去 数组长度就变长了length: “hello”的长度 5,capacity: 分配的总空间 21,21这个数量,不同的JDK数量是不一样的

练习题

1)自然对数e的计算

​ 借助Math的方法,把自然对数计算出来,看看经过自己计算的自然对数和Math.E的区别有多大

/***
 *自然对数的计算方式
 */
public class Exercise {
    public static void main(String[] args){
        double myE = 1;
        int n = Integer.MAX_VALUE;
        System.out.println("系  统:\t"+Math.E);
        for (int i = 1; i < n; i++) {
           myE = myE * (1+(double)1/n);
        }
        System.out.println("计算的:\t"+myE);
    }
}
2)质数计算

​ 统计找出一千万以内,一共有多少质数,质数概念: 只能被1和自己整除的数

/***
 *质数计算
 * 使用这个Math.sqrt(i),提高效率(不太好理解)
 */
public class Exercise {
    public static void main(String[] args){
        long start = System.currentTimeMillis();
        int count = 0;
        boolean isPrimeNumber = true;
        for (int i = 2; i <= 10000000; i++) {
//            if(i%2==0 && i!=2){continue;}
            for (int j = 2; j <= Math.sqrt(i); j++) {
                if(i%j == 0){
                    isPrimeNumber = false;
                    break;
                }
            }
            if(isPrimeNumber){
                count++;
            }else{
                isPrimeNumber = true;
            }
        }
        System.out.printf("千万以内的质数数量:%d%n",count);
        long end = System.currentTimeMillis();
        System.out.printf("花费时间: %sms" , (end - start));
    }

}
3)练习-Character

​ 通过Scanner从控制台读取字符串,然后把字符串转换为字符数组

​ 参考的转换方式:char[] cs = str.toCharArray();

​ 转换为字符数组后,筛选出控制台读取到的字符串中的大写字母和数字,并打印出来

import java.util.Scanner;
/***
 *
 * 使练习-Character
 */
public class Exercise {
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入字符串:");
        String str = scanner.nextLine();
        char[] ch = str.toCharArray();
        for (char c : ch) {
            if (Character.isUpperCase(c) || Character.isDigit(c)) {
                System.out.print(c + "\t");
            }
        }
    }
}
4)练习-随机字符串

​ 创建一个长度是5的随机字符串,随机字符有可能是数字,大写字母或者小写字母

​ 提示:创建随机数字,然后ASCII码转成字符

/***
 *48-57数组   65-90大写     97-122小写
 * 使练习-Character
 */
public class Exercise {
    public static void main(String[] args) {
        char[] c = new char[16];

        for (int i = 0; i < c.length; i++) {
            while (true) {
                char rd = (char) (Math.random() * 74 + 48);
                //此处也可以用isDigit判断数字,用isLetter判断是不是字母
                if ((rd >= 48 && rd <= 57) || (rd >= 65 && rd <= 90) || (rd >= 97 && rd <= 122)) {
                    c[i] = rd;
                    break;
                }
            }
        }
        System.out.print(String.valueOf(c));
    }
}
5)练习-字符串数组排序

​ 创建一个长度是8的字符串数组,使用8个长度是5的随机字符串初始化这个数组,对这个数组进行排序,按 照每个字符串的首字母排序(无视大小写)

1: 不能使用Arrays.sort() 要自己写
2: 无视大小写

import java.util.Arrays;
/**
 *48-57数字   65-90大写     97-122小写
 * 练习-字符串数组排序
 */
public class Exercise {
    public static void main(String[] args) {
        String[] str = new String[20];
        for (int i = 0; i < str.length; i++) {
            str[i] = getString();
        }
        System.out.println(Arrays.toString(str));
        sort(str);
        System.out.println(Arrays.toString(str));
    }

    public static String getString() {
        char[] c = new char[5];
        for (int i = 0; i < c.length; i++) {
            while (true) {
                char rd = (char) (Math.random() * 74 + 48);
                //此处也可以用isDigit判断数字,用isLetter判断是不是字母
                if (Character.isDigit(rd) || Character.isLetter(rd)) {
                    c[i] = rd;
                    break;
                }
            }
        }
        return String.valueOf(c);
    }

    public static void sort(String[] str) {

        String temp ;
        for (int i = 0; i < str.length-1; i++) {
            for (int j = 0; j < str.length-1-i; j++) {
                //忽略大小写就是都转换成小写或大写比较,数值转换大小写不变
                if(Character.toLowerCase(str[j].charAt(0)) > Character.toLowerCase(str[j+1].charAt(0))){
                    temp = str[j];
                    str[j] = str[j+1];
                    str[j+1] = temp;
                }
            }
        }
    }
}
6)练习-穷举法破解密码

​ 生成一个长度是3的随机字符串,把这个字符串作为当做密码,使用穷举法生成长度是3的字符串,匹配 上述生成的密码

​ 要求: 分别使用多层for循环 和 递归解决上述问题

import java.util.Arrays;
/**
 * 三位数密码破解
 * 穷举法
 */
public class Exercise {
    public static void main(String[] args) {
        String str = getString(3);
        char[] c = new char[3];//存放待比较的密码
        System.out.println(str);
        String code = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
//        System.out.println(code.substring(1,2));
        for (int i = 0; i < 62; i++) {
            for (int j = 0; j < 62; j++) {
                for (int k = 0; k < 62; k++) {
                    c[0] = code.charAt(i);
                    c[1] = code.charAt(j);
                    c[2] = code.charAt(k);
                    String str1 = String.valueOf(c);
                    if (str.equals(str1)) {
                        System.out.printf("密码为:%s", str1);
                        i = 62; //猜到密码就终止
                        j = 62; //猜到密码就终止
                        break; //猜到密码就终止
                    }
                }
            }
        }

    }
    public static String getString(int len) {
        char[] c = new char[len];
        for (int i = 0; i < c.length; i++) {
            while (true) {
                char rd = (char) (Math.random() * 74 + 48);
                //此处也可以用isDigit判断数字,用isLetter判断是不是字母
                if (Character.isDigit(rd) || Character.isLetter(rd)) {
                    c[i] = rd;
                    break;
                }
            }
        }
        return String.valueOf(c);
    }
}
6-1)练习-递归法破解密码
import java.util.Arrays;
/**
 * 三位数密码破解
 * 递归法
 */
public class Exercise {
    public static void main(String[] args) {
        String str = getString(3);

        String found = new String("");
        char[] c = new char[3];//存放待比较的密码
        System.out.printf("生成密码为:%s%n",str);
        found =  getPass(str,found);
        System.out.printf("破解密码为:%s%n",found);

    }

    public static String getString(int len) {
        char[] c = new char[len];
        for (int i = 0; i < c.length; i++) {
            while (true) {
                char rd = (char) (Math.random() * 74 + 48);
                //此处也可以用isDigit判断数字,用isLetter判断是不是字母
                if (Character.isDigit(rd) || Character.isLetter(rd)) {
                    c[i] = rd;
                    break;
                }
            }
        }
        return String.valueOf(c);
    }

    /**
     * 这个递归是单趟的
     * 执行逻辑:
     *      1、调用getpass传递随机密码和破解密码
     *      2、比较两个密码是否相等
     *          不相等的话,遍历62次循环去找出第一个字符
     *                 如果找到字符,把字符拼接在found里,并且递归进行下一个字符的查找
     *                 三次递归完成后pass.equals(found)就为true
     *                 如果找不到字符,return"该密码中包含了特殊字符"
     *          相等的话,return一个破解的密码
     * 
     * @param pass 传递进去系统生成的随机密码
     * @param found 传递进去破解的密码,首次传递空字符串,
     *              第二次递归进去传递的是找到的第一个字符,
     *              依次类推,三次递归,就会把found填充到三个字符,也就是密码
     * @return 返回破解后的密码
     */
    public static String getPass(String pass,String found){
        String code = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        if(!pass.equals(found)) {
            char[] passChar = pass.toCharArray();
            for (int i = 0; i < 62; i++) {
                //因为found每次递归完都会给增加一个字符,所以他的length是递增的
                //刚好用来指示比较的是哪一个索引
                if (passChar[found.length()] == code.charAt(i)) {
                    found = found + code.charAt(i);
                    return getPass(pass, found);
                }
            }
            return "该密码中包含了特殊字符";
        }
        else{
            return found;
        }
    }
}
7)练习-每个单词的首字母都转换为大写

​ 给出一句英文句子: “let there be light”,得到一个新的字符串,每个单词的首字母都转换为大写

import java.util.Arrays;
/**
 * 每个单词的首字母都转换为大写
 * 65-90大写     97-122小写
 */
public class Exercise {
    public static void main(String[] args) {
        String str = "you don't have to worry anymore about the window being resized";
        System.out.println(str);
        String[] strArray = str.split(" ");//以空格分割成字符串数组
        for (int i = 0; i < strArray.length; i++) {
            if (Character.isLowerCase(strArray[i].charAt(0))) {
                char c = Character.toUpperCase(strArray[i].charAt(0));
                //第一个字符转换为大写后,必须再转换成字符串,才能使用在replaceFirst中
                String firstCharToString = Character.toString(c);
                //正则表示式,意思只要第一个字符是a-z全部换成大写
                strArray[i] = strArray[i].replaceFirst("[a-z]", firstCharToString);
            }
        }
        String str3 ="";
        for (int i = 0; i < strArray.length; i++) {
            //最终此处应该使用StringBuffer
            str3 = str3 + strArray[i]+" ";
        }
        System.out.println(str3);
    }

}
8)练习-统计以p开头的单词数

​ peter piper picked a peck of pickled peppers,统计这段绕口令有多少个以p开头的单词

import java.util.Arrays;
/**
 * 统计以p开头的单词数
 * 65-90大写     97-122小写
 */
public class Exercise {
    public static void main(String[] args) {
        String str = "peter piper picked a peck of pickled peppers";
        System.out.println(str);
        int count = 0;
        String[] strArray = str.split(" ");//以空格分割成字符串数组
        for (int i = 0; i < strArray.length; i++) {
            if (strArray[i].charAt(0) == 'p') {
               count++;
            }
        }
        System.out.printf("一共有%s个以p开头的单词%n",count);
    }
}
9)练习-间隔大写小写模式

​ 把 lengendary 改成间隔大写小写模式,即 LeNgEnDaRy

/**
 * 间隔大写小写模式
 * 65-90大写     97-122小写
 */
public class Exercise {
    public static void main(String[] args) {
        String str = "lengendary";
        String str1 = "";
        System.out.println(str);
        for (int i = 0; i < str.length(); i++) {
            if (i % 2 == 0) {
                str1 = str1 + str.substring(i, i + 1).toUpperCase();
            } else {
                str1 = str1 + str.substring(i, i + 1);
            }
        }
      System.out.printf("转换后%s%n",str1);
    }
}
10)练习-最后一个字母变大写

​ 把 lengendary 最后一个字母变大写

/**
 * 最后一个字母变大写
 * 65-90大写     97-122小写
 */
public class Exercise {
    public static void main(String[] args) {
        String str = "lengendary";
        String str1 = "";
        System.out.println(str);
        str1 = str.substring(0,str.length()-1) +Character.toUpperCase(str.charAt(str.length()-1));
        System.out.printf("转换后%s%n",str1);
    }
}
11)练习-把最后一个目标单词首字母大写

​ Nature has given us that two ears, two eyes, and but one tongue, to the end that we should hear and see more than we speak,把最后一个two单词首字母大写

/**
 * 把最后一个targetString单词首字母大写
 * 65-90大写     97-122小写
 */
public class Exercise {
    public static void main(String[] args) {
        String targetString = "and";
        String str = "Nature has given us that two ears, two eyes, and but one tongue" +
                ", to the end that we should hear and see more than we speak";
        String str1 = "";
        int  index = 0;
        System.out.printf("转换后%s%n",str);
        index = str.lastIndexOf(targetString);
        //目标字符前面字符串+目标字符转大写+目标字符后面的字符串
        str1 = str.substring(0,index) + Character.toUpperCase(str.charAt(index))+str.substring(index+1);
        System.out.printf("转换后%s%n",str1);
    }
}
12)练习-比较字符串

​ 创建一个长度是100的字符串数组,使用长度是2的随机字符填充该字符串数组,统计这个字符串数组里 重复的字符串有多少种

import java.util.Random;
/**
 * 比较字符串
 * 65-90大写     97-122小写
 */
public class Exercise {
    public static void main(String[] args) {
        String base = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        String[] strArray = new String[100];
        for (int i = 0; i < strArray.length; i++) {
            Random rand = new Random();
            strArray[i] = "" + base.charAt(rand.nextInt(62)) +
                    base.charAt(rand.nextInt(62));
            System.out.print(strArray[i] + "  ");
            if ((i + 1) % 20 == 0) {
                System.out.println();
            }
        }
//        String[] strArray = {"jh","jh","fg","jh","ds","jh","jh","jh","fg","bv","jh"};
        for (int i = 0; i < strArray.length; i++) {
            int count = 1;
            for (int j = i + 1; j < strArray.length; j++) {
                if (strArray[i].equals("")) {//如果是空串不比较,跳过进行下一个元素比较
                    break;
                } else {
                    if (strArray[i].equals(strArray[j])) {
                        strArray[j] = "";//把重复字符串置空,让再循环到该空串时,跳过,避免重复比较
                        count++;
                    }
                }
            }
            if (count != 1) {
                System.out.printf("%s的重复数为%d%n", strArray[i], count);
            }
        }
    }
}
13)练习-StringBuffer性能

​ 生成10位长度的随机字符串,分别使用String的+和StringBuffer,连接10000个随机字符串,计算消耗的 时间

/**
 * StringBuffer性能
 * 65-90大写     97-122小写
 */
public class Exercise {
    public static void main(String[] args) {
        String base = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        String str = "";
        StringBuffer sb = new StringBuffer();
        long stime = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            str += getString(10);
        }
        long etime = System.currentTimeMillis();
        System.out.printf("用+号总花费时间:%dms%n", etime - stime);
        long stime1 = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            sb.append(getString(10));
        }
        long etime1 = System.currentTimeMillis();
        System.out.printf("用StringBuffer总花费时间:%dms%n", etime1 - stime1);
    }
    public static String getString(int len) {
        char[] c = new char[len];
        for (int i = 0; i < c.length; i++) {
            while (true) {
                char rd = (char) (Math.random() * 74 + 48);
                //此处也可以用isDigit判断数字,用isLetter判断是不是字母
                if (Character.isDigit(rd) || Character.isLetter(rd)) {
                    c[i] = rd;
                    break;
                }
            }
        }
        return String.valueOf(c);
    }
}
14)练习-MyStringBuffer

Exercise.java

/**
 * MyStringBuffer性能
 * 65-90大写     97-122小写
 */
public class Exercise{
    public static void main(String[] args) {
        MyStringBuffer sb = new MyStringBuffer("abc");
        System.out.println(sb.length());
        System.out.println(sb.capacity());
        System.out.println(sb.toString());

        sb.append("123");
        System.out.println(sb.length());
        System.out.println(sb.capacity());
        System.out.println(sb.toString());

        sb.append("987654321");
        System.out.println(sb.length());
        System.out.println(sb.capacity());
        System.out.println(sb.toString());

        sb.append('w');
        System.out.println(sb.length());
        System.out.println(sb.capacity());
        System.out.println(sb.toString());

        sb.insert(4,'o');
        System.out.println(sb.length());
        System.out.println(sb.capacity());
        System.out.println(sb.toString());

        sb.insert(5,"WCO");
        System.out.println(sb.length());
        System.out.println(sb.capacity());
        System.out.println(sb.toString());

        sb.delete(5,8);
        System.out.println(sb.length());
        System.out.println(sb.capacity());
        System.out.println(sb.toString());

        sb.reverse();
        System.out.println(sb.length());
        System.out.println(sb.capacity());
        System.out.println(sb.toString());

    }

}

MyStringBuffer.java

public class MyStringBuffer implements InterfaceStringBuffer {
    private char[] ch; //内部管理的个字符数组
    private int len; // 全局都要使用的数组内有效元素的个数

    public MyStringBuffer() {
        ch = new char[16];//创建对象要默认创建一个大小16的空数组
    }

    public MyStringBuffer(String str) {
        ch = new char[16];
        append(str);//当创建对象时传递了一个字符串,则调用内部的append去添加
    }

    @Override
    public void append(String str) {
        insert(len,str);
    }

    @Override
    public void append(char c) {
        insert(len,c);
    }

    @Override
    public void insert(int pos, char b) {
        insert(pos,String.valueOf(b));
    }

    @Override
    public void insert(int pos, String b) {
        if(pos < 0 || pos>len){
            return;
        }
        char[] c = b.toCharArray();
        char[] temp = new char[capacity()];
        while (len+c.length > temp.length){//一步一步扩容
            temp = new char[temp.length*2 + 2];//原数组要进行扩容
        }
        System.arraycopy(ch, 0, temp, 0, pos);
        System.arraycopy(c, 0, temp, pos, c.length);
        System.arraycopy(ch, pos, temp, pos + c.length, len - pos);
        ch = temp;
        len = len + b.length();
    }

    @Override
    public void delete(int start) {
        delete(start,len);

    }

    @Override
    public void delete(int start, int end) {
        /*
         * 总体思想就是清零ch数组
         * 再把删除后的数组元素一个一个append进去
         * 这样可以避免过分关注ch数组大小和有效元素的问题
         * 全部由append去处理,最终还是由insert处理
         * 所以insert一定要写全面一点
         */
        if (end - start <= 0) {
            return;
        }
        if (start < 0) {
            return;
        }
        if (end > len) {
            return;
        }
        char[] temp = ch; //把ch数组缓存
        ch = new char[16];//ch数组清零
        int lentemp = len;//长度缓存,到时循环时需要用到
        len = 0;//ch都清零了,配套的len也得清零
        for (int i = 0; i < start; i++) {
            append(temp[i]);
        }
        for (int i = end; i < lentemp; i++) {
            append(temp[i]);
        }
    }
    @Override
    public void reverse() {
        char[] temp = new char[capacity()];
        for (int i = 0; i < len; i++) {
            System.arraycopy(ch, i, temp, len - 1 - i, 1);
        }
        ch = temp;
    }

    @Override
    public int length() {
        return len;
    }

    public int capacity() {

        return ch.length;
    }

    public String toString() {
        char[] temp = new char[len];
        System.arraycopy(ch, 0, temp, 0, len);//避免打印后字符串后面有很多空字符
        return String.valueOf(temp);
    }
}

InterfaceStringBuffer.java

public interface InterfaceStringBuffer {
    public void append(String str); //追加字符串
    public void append(char c);  //追加字符
    public void insert(int pos,char b); //指定位置插入字符
    public void insert(int pos,String b); //指定位置插入字符串
    public void delete(int start); //从开始位置删除剩下的
    public void delete(int start,int end); //从开始位置删除结束位置-1
    public void reverse(); //反转
    public int length(); //返回长度
}

6)输入输出

输入Scanner的使用

例:

//创建一个scanner对象
Scanner scanner = new Scanner(System.in);
System.out.println("请输入:");
String s =  scanner.next();
System.out.println("您输入的是:" + s);
//关闭输入流,不关闭会一直占用资源
scanner.close();

next()和nextLine()的区别

​ next() 一定要输入有效字符才能结束,空格为结束标志

​ nextLine() 以回车作为结束标志

判断是否为指定数据类型

​ scanner.hasNextXXX 来检查输入的类型

读取了整数后,接着读取字符串

需要注意的是,如果在通过nextInt()读取了整数后,再接着读取字符串,读出来的是回车换行:“\r\n”,因为nextInt仅仅读取数字信息,而不会读取回车换行"\r\n".所以,如果在业务上需要读取了整数后,接着读取字符串,那么就应该连续执行两次nextLine(),第一次是取走回车换行,第二次才是读取真正的字符串

格式化输出

格式化

​ 如果不使用格式化输出,就需要进行字符串连接,如果变量比较多,拼接就会显得繁琐

转 换 符说 明示 例
%s字符串类型“string”
%c字符类型‘m’
%b布尔类型true
%d整数类型(十进制)99
%x整数类型(十六进制)FF
%o整数类型(八进制)77
%f浮点类型99.99
%a十六进制浮点类型FF.35AE
%e指数类型9.38e+5
%g通用浮点类型(f和e类型中较短的)
%h散列码
%%百分比类型
%n换行符
%tx日期与时间类型(x代表不同的日期与时间转换符)
public class Exercise {
    public static void main(String[] args) {
        String name = "老张";
        String gender = "男";
        int age = 39;
        int height = 170;
        String info = "本人%s,%s,%d岁,身高%d";
        System.out.printf(info, name, gender, age, height);
        System.out.format(info, name, gender, age, height);
    }
}

​ printf和format能够达到一模一样的效果,在printf中直接调用了format

//不同国家的千位分隔符
        System.out.format(Locale.FRANCE,"%,.2f%n",Math.PI*10000);
        System.out.format(Locale.US,"%,.2f%n",Math.PI*10000);
        System.out.format(Locale.UK,"%,.2f%n",Math.PI*10000);

搭配转换符的标志,如图所示

标志说 明示 例结 果
+为正数或者负数添加符号(“%+d”,15)+15
左对齐(5个空位,然后左对齐)(“%-5d”,15)|15 |
0数字前面补0(“%04d”, 99)0099
空格在整数之前添加指定数量的空格(“% 4d”, 99)| 99|
,以“,”对数字分组(“%,f”, 9999.99)9,999.990000
(使用括号包含负数(正数没用)(“%(f”, -99.99)(99.990000)
#如果是浮点数则包含小数点,如果是16进制或8进制则添加0x或0(“%#x”, 99)(“%#o”, 99)0x630143
<格式化前一个转换符所描述的参数(“%f和%❤️.2f”, 99.45)99.450000和99.45
$被格式化的参数索引(“%1 d , d,%2 d,s”, 99,“abc”)99,abc

常见日期和时间组合的格式,如图所示。

转 换 符说 明示 例
c包括全部日期和时间信息星期六 十月 27 14:21:20 CST 2007
F“年-月-日”格式2007-10-27
D“月/日/年”格式10/27/07
r“HH:MM:SS PM”格式(12时制)02:25:51 下午
T“HH:MM:SS”格式(24时制)14:28:16
R“HH:MM”格式(24时制)14:28

日期格式转换符

转 换 符说 明示 例
b月份简称Sep
B月份全称September
a星期简称Mon
A星期全称Monday
C年的前两位数字(不足两位前面补0)20
y年的后两位数字(不足两位前面补0)22
j一年中的天数(即年的第几天)076
m两位数字的月份(不足两位前面补0)03
d两位数字的日(不足两位前面补0)17
e月份的日(前面不补0)17

时间格式的转换符

转 换 符说 明示 例
H2位数字24时制的小时(不足2位前面补0)15
I2位数字12时制的小时(不足2位前面补0)03
k2位数字24时制的小时(前面不补0)15
l2位数字12时制的小时(前面不补0)3
M2位数字的分钟(不足2位前面补0)03
S2位数字的秒(不足2位前面补0)09
L3位数字的毫秒(不足3位前面补0)015
N9位数字的毫秒数(不足9位前面补0)562000000
p小写字母的上午或下午标记中:下午英:pm
z相对于GMT的RFC822时区的偏移量+0800
Z时区缩写字符串CST
s1970-1-1 00:00:00 到现在所经过的秒数1193468128
Q1970-1-1 00:00:00 到现在所经过的毫秒数1193468128984

换行符

​ 换行符就是另起一行 — ‘\n’ 换行(newline),回车符就是回到一行的开头 — ‘\r’ 回车(return)

​ 在idea里敲一个回车,实际上是回车换行符

​ 然而在不同的操作系统,换行符是不一样的

​ (1)在DOS和Windows中,每行结尾是 “\r\n”;

​ (2)Linux系统里,每行结尾只有 “\n”;

​ (3)Mac系统里,每行结尾是只有 “\r”。

​ 为了使得同一个java程序的换行符在所有的操作系统中都有一样的表现,使用%n,就可以做到平台无关的换行 System.out.printf("%n");注意一定要是printf而不是print

7)控制流程

表达式

表达式是由变量、运算符和方法调用组成的构造,这些构造根据语言的语法构造,计算结果为单个值

编写复合表达式时,要明确并用括号指出应首先计算哪些运算符。这种做法使代码更易于阅读和维护

语句

语句大致相当于自然语言中的句子。一条语句构成一个完整的执行单元。通过以分号 ( ;)结束表达式

还有另外两种语句:声明语句控制流语句声明语句声明一个变量,控制流语句控制语句执行的顺序

是一组位于一对大括号之间的零个或多个语句,可以在任何允许使用单个语句的地方使用。

顺序结构

​ 程序从上往下一条一条执行

if选择结构

​ 语法格式

if(布尔表达式){
    //如果布尔表达式为true,则执行语句
}
if(布尔表达式){
    //如果布尔表达式为true,则执行语句
}else{
    //如果布尔表达式为false,则执行语句
}
if(布尔表达式1){
    //如果布尔表达式1为true,则执行语句
}else if(布尔表达式2){
    //如果布尔表达式2为true,则执行语句
}else if(布尔表达式3){
    //如果布尔表达式3为true,则执行语句
}else{
    //如果以上表达式都不为true,则执行语句
}

switch选择结构

​ switch可以使用byte,short,int,char,String,enum

​ String在Java1.7之前是不支持的, Java从1.7开始支持switch用String的,编译后是把String转化为hash值,其实还是整数

​ 语法格式

switch(expression){
    case value:
        //语句
        break;
    case value:
        //语句
        break;
    default:
        //语句
}

while循环结构

​ 语法结构

while(expression){
    //只要表达式为真,一直执行语句,直到为false
}
do{
    //至少执行一次的语句
}while(expression);

​ while先判断后执行语句,dowhile是先执行后判断

for循环结构

​ 语句结构

for(初始化;布尔表达式;更新){
    //代码
}

增强的for循环

语句结构
for(声明语句:表达式){
    //代码块
}

​ 声明语句:声明新的局部变量,该变量类型和数组元素类型一致,其值和此时数组元素值相等

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

break、continue

​ break 结束整个循环

​ continue 结束本次循环

​ 带标签的break和continue

​ 标签是指后面跟一个冒号的标识符(不建议使用)

练习题

(1)计算0-100奇数和偶数的和
/***
 * 计算0-100之间的奇数和偶数的和
 */
public class Exercise {
    public static void main(String[] args) {
        int oddSum = 0;
        int evenSum = 0;
        for (int i = 0; i <= 100; i++) {
            if (i % 2 == 0) {
                evenSum += i;
            } else {
                oddSum += i;
            }
        }
        System.out.println("偶数和为:" + evenSum);
        System.out.println("奇数和为:" + oddSum);
    }
}
控制台输出
    偶数和为:2450
	奇数和为:2500
(2)计算BMI(肥胖指数)

​ 根据键盘输入的身高体重,判断肥胖指数(BMI),BMI的计算公式是 体重(kg) / (身高*身高)

import java.util.Scanner;
/***
 * 根据键盘输入的身高体重,判断肥胖指数(BMI)
 */
public class Exercise {
    public static void main(String[] args) {
        float bmi = 0f;
        float weight = 0f;
        float height = 0f;
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入体重(kg):");
        weight = scanner.nextFloat();
        System.out.println("请输入身高(m)");
        height = scanner.nextFloat();
        bmi = weight/(height * height);
        if(bmi < 18.5){
            System.out.println("当前BMI是:" + bmi);
            System.out.println("身体状态是:体重过轻");
        }else if(18.5 <= bmi && bmi < 24){
            System.out.println("当前BMI是:" + bmi);
            System.out.println("身体状态是:正常体重");
        }else if(24 <= bmi && bmi < 27){
            System.out.println("当前BMI是:" + bmi);
            System.out.println("身体状态是:体重过重");
        }else if(27 <= bmi && bmi < 30){
            System.out.println("当前BMI是:" + bmi);
            System.out.println("身体状态是:轻度肥胖");
        }else if(30 <= bmi && bmi < 35){
            System.out.println("当前BMI是:" + bmi);
            System.out.println("身体状态是:中度肥胖");
        }else {
            System.out.println("当前BMI是:" + bmi);
            System.out.println("身体状态是:重度肥胖");
        }
    }
}
控制台输出
	请输入体重(kg):
	85
	请输入身高(m)
	1.78
	height = 1.78
	weight = 85.0
	当前BMI是:26.827423
	身体状态是:体重过重
(3)判断某一年是否为闰年

​ 通过Scanner输入一个年份,然后判断该年是否是闰年

​ 闰年判断标准(满足任何一个)

​ 1、如果能够被4整除,但是不能被100整除

​ 2、能够被400整除

import java.util.Scanner;
/***
 * 判断某一年是不是为闰年
 */
public class Exercise {
    public static void main(String[] args) {
        int year = 0;
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入年份:");
        while (scanner.hasNextInt()) {
            year = scanner.nextInt();
            if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
                System.out.println(year + "是闰年");
            } else {
                System.out.println(year + "是平年");
            }
            System.out.println("请输入年份:");
        }
    }
}
控制台输出
	请输入年份:
	1990
	1990是平年
(4)月份判断季节

​ 通过Scanner输入月份,然后使用switch 判断季节

import java.util.Scanner;
/***
 * 判断月份属于的季节
 */
public class Exercise {
    public static void main(String[] args) throws Exception {
        int month = 0;
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入月份:");
        while (scanner.hasNextInt()) {
            month = scanner.nextInt();
            if (month>0 && month<=3) {
                System.out.println(month + "月是春天");
            } else if(month>3 && month<=6) {
                System.out.println(month + "月是夏天");
            }
            else if(month>6 && month<=9) {
                System.out.println(month + "月是秋天");
            }
            else if(month>9 && month<=12) {
                System.out.println(month + "月是冬天");
            }else {
                System.out.println("!!!!!!!输入正确的月份!!!!!!!!");
            }
            System.out.println("请输入月份:");
        }
        System.out.println("输入了非法字符,程序退出");
    }
}
(5)计算阶乘

​ 通过Scanner获取一个整数,然后使用while计算这个整数的阶乘,N的阶乘等于 N* (N-1) * (N-2) * … * 1

import java.util.Scanner;
/***
 * 计算阶乘
 */
public class Exercise {
    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输要计算的整数:");
        while (scanner.hasNextInt()) {
            long result = 1;
            int i = scanner.nextInt();
            while (i > 0) {
                result *= i;
                i -= 1;
            }
            System.out.println("结果为:" + result);
(6)细胞分裂

​ 第一天1个,第二天2个,第三天4个,第四天8个,以此类推。求第十天有多少细胞?

/***
 * 细胞分裂
 */
public class Exercise {
    public static void main(String[] args) {
        int day = 10;
        long count = 1;
        for (int i = 1; i <= day; i++) {
            count = count * 2;
        }
        System.out.println(day + "天结束细胞总量为:" + count);
    }
}
10天结束细胞总量为:1024
(7)被5整除的数

​ 用while或for循环输出1-1000之间能被5整除的数,并且每行输出3个

/***
 * 输出1-1000之间能被5整除的数,并且每行输出3个
 */
public class Exercise {
    public static void main(String[] args) {
        int num = 1000;
        for (int i = 1; i < 1000; i++) {
            if (i % 5 == 0){
                System.out.print(i);
                if(i % 3 == 0){
                    System.out.print("\n");//第三个数字结尾换行
                }else {
                    System.out.print("\t");//另外两个数字结尾tab
                }
            }
        }
    }
}
(8)打印九九乘法表
/***
 * 打印乘法表
 */
public class Exercise {
    public static void main(String[] args) {
        for (int i = 1; i <= 9; i++) {
            for (int j = 1; j <= i; j++) {
                System.out.print(j +"×" + i +"=" + i * j);
                System.out.print("\t");
            }
            System.out.println();
        }
    }
}
(9)打印三角形
/***
 * 打印三角形
 */
public class Exercise {
    public static void main(String[] args) {
        int line = 20;
        for (int i = 0; i < line; i++) {
            for (int j = line; j > i; j--) {
                System.out.print(" ");
            }
            for (int j = 0; j < (2 * i + 1); j++) {
                System.out.print("*");
            }
            System.out.println();
        }
    }
}

(10)利息计算

​ 每年投资12000,投资回报率为20%,持续投资多少年,总收入达到100万。

​ 复利公式:F = p* ( (1+r)^n ); (F 最终收入, p 本金 ,r 年利率 ,**n **存了多少年)

/***
 * 每年投资12000,投资回报率为20%,持续投资多少年,总收入达到100万
 */
public class Exercise {
    public static void main(String[] args) {
        int assets = 0;
        int principal = 0;
        int investment = 12000;
        float APR = 0.2f;
        int year = 0;
        while (assets<1000000){
            principal = assets+investment;//年初向总资产中投入12000
            assets=(int)(principal*(1+APR));//年末所得总资产
            year++;
            System.out.println("第"+year+"年总资产"+assets);
        }
        System.out.println("需要"+year+"年资产达到"+assets);
    }
}
(11)寻找指定规则的数

​ 寻找某两个数相除,其结果 离黄金分割点 0.618最近

​ 分母和分子不能同时为偶数
​ 分母和分子 取值范围在[1-20]

/***
 * 寻找某两个数相除,其结果 离黄金分割点 0.618最近
 */
public class Exercise {
    public static void main(String[] args) {
        float f = 0f;
        float resalt = 0f;
        float preResalt = 1f;
        int currentI = 0;
        int currentJ = 0;
        //只遍历了分母大于分子的数
        for (int i = 1; i < 20; i++) {
            for (int j = 20; j > i; j--) {
                f = (float) i / j;
                resalt = f - 0.618f;//每次相除后进行比较
                resalt = (resalt > 0) ? resalt : -(resalt);//比较结果取绝对值(没用math)
                if(resalt < preResalt){
                    preResalt = resalt; //如果比较值比上一次小,将结果替换
                    currentI = i;//记录当时最小时的i
                    currentJ = j;//记录当时最小时的j
                }
            }
        }
        System.out.println("离黄金分割两个数相除最近的是:"+currentI + "/" + currentJ + "=" + (float) currentI / currentJ);
    }
}
(12)寻找所有的水仙花数

​ 水仙花数定义:一定是3位数,每一位的立方,加起来恰好是这个数本身,比如153=1*1*1+5*5*5+3*3*3

/***
 * 寻找所有的水仙花数
 */
public class HelloWorld {
    public static void main(String[] args) {
        int ge = 0;
        int shi = 0;
        int bai = 0;
        for (int i = 100; i < 1000; i++) {
           ge =  i/1%10;
           shi = i/10%10;
           bai = i/100%10;
           if(i == (ge*ge*ge)+(shi*shi*shi)+(bai*bai*bai)) {
               System.out.println(i+"为水仙花数");
           }
        }
    }
}
(13)小学算术题

​ 求方框的数字

□ + □ = 8
+   +
□ - □ = 6
‖   ‖
14 10
/***
 * 小学算术题
 */
public class HelloWorld {
    public static void main(String[] args) {
        int a = 0;//最大值8
        int b = 0;//最大值8
        int c = 0;//最大值14
        int d = 0;//最大值10
        for (a = 0; a <= 8; a++) {
            for (b = 0; b <= 8; b++) {
                for (c = 0; c <= 14; c++) {
                    for (d = 0; d <= 10; d++) {
                        if((a+b)==8&&(b+d)==10&&(c-d)==6&&(a+c)==14){
                            System.out.print(a+"\t");
                            System.out.print(b+"\t");
                            System.out.print(c+"\t");
                            System.out.print(d+"\t");
                            System.out.println();
                        }
                    }
                }
            }
        }
    }
}

结果3	5	11	5

8)数组

数组的声明与创建

​ 数组是一个固定长度的,包含了相同类型数据的 容器

​ int[] a; 声明了一个数组变量,仅声明没创建

​ 创建数组的时候,要指明数组的长度。new int[5];

​ 数组下标从0开始,下标0,代表数组里的第一个数

.length属性用于访问一个数组的长度,数组访问下标范围是0到(长度-1),一旦超过这个范围,就会产生数组下标越界异常

初始化数组

//先创建,后赋值
int[] a = new int[5];
a[0] = 1;

//创建的同时赋值,两种写法
int[] a1 = new int[]{1,2,3,4};
int[] a2 = {1,2,3,4,5};

数组的使用

​ for each循环遍历数组

int[] a2 = {1,2,3,4,5};
for (int i:a2) {
	System.out.println(i);
}

​ 数组作为方法的参数

public static void meth(int[] i){
	System.out.println(Arrays.toString(i));
}

​ 数组做为返回值

public static int[] meth(int[] a){
	int[] a1 = new int[a.length];
	for (int i = 0; i < a.length ; i++) {
		a1[i] = a[i]+10;
	}
	return a1;
}

二维数组

​ 二维数组里面的每一个元素,都是一个一维数组,所以二维数组又叫数组的数组

int[][] a = new int[2][3];
a[1][2] = 5;

Arrays类

​ Arrays是针对数组的工具类,可以进行 排序,查找,复制填充等功能。 大大提高了开发人员的工作效率。

​ 类里面为static的方法可以直接类名调用,

int[] a = new int[5];
Arrays.toString(a);//转换字符串
Arrays.copyOfRange(a, "0", "3")//复制数组
Arrays.toString(a)//数组排序 
Arrays.binarySearch(a, 62)//搜索62在a数组中的位置,使用前必须给数组排序
Arrays.equals(a, b)//比较两个数组的内容是否一样
Arrays.fill(a, 5)//使用5填充数组

数组排序

​ 选择排序,把第一位和其他所有的进行比较,只要比第一位小的,就换到第一个位置来比较完后,第一位就是最小的然后再从第二位和剩余的其他所有进行比较,只要比第二位小,就换到第二个位置来比较完后,第二位就是第二小的,依次类推

import java.util.Arrays;
/***
 * 选择排序
 */
public class Exercise {
    public static void main(String[] args) {
        int[] array = new int[5] ;
        for (int i = 0; i < array.length-1; i++) {
            int rdom = (int) (Math.random() * 100);
            array[i] = rdom;
        }
        System.out.println("原数组"+Arrays.toString(array));
        int[] array2 = sort(array);
        System.out.println("排序后"+Arrays.toString(array2));
    }
    public static int[] sort(int[] a){
        int temp;
        for (int i = 0; i < a.length-1 ; i++) {
            //后一次进入大循环比较的循环往后推移一个元素,所以j = i+1
            for (int j = i+1; j < a.length ; j++) {
                if(a[i] > a[j]){
                    temp = a[i];
                    a[i] = a[j];
                    a[j] = temp;
                }
            }
        }
        return a;
    }
}

​ 冒泡排序,第一步:从第一位开始,把相邻两位进行比较如果发现前面的比后面的大,就把大的数据交换在后面,循环比较完毕后,最后一位就是最大的第二步: 再来一次,只不过不用比较最后一位

import java.util.Arrays;
/***
 * 冒泡排序
 */
public class Exercise {
    public static void main(String[] args) {
        int[] array = new int[5] ;
        for (int i = 0; i < array.length-1; i++) {
            int rdom = (int) (Math.random() * 100);
            array[i] = rdom;
        }
        System.out.println("原数组"+Arrays.toString(array));
        int[] array2 = sort(array);
        System.out.println("排序后"+Arrays.toString(array2));
    }
    public static int[] sort(int[] a){
        int temp;
        for (int i = 0; i < a.length-1 ; i++) {
            for (int j = 0; j < a.length-1-i ; j++) {
                if(a[j] > a[j+1]){
                    temp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = temp;
                    System.out.println("显示每一步"+Arrays.toString(a));
                }
            }
        }
        return a;
    }
}

稀疏数组

​ 保存一个二维数组时,如果里面很多默认值为零或同一个值,因此记录了很多没有意义的数,使用稀疏数组可以解决这个问题

稀疏数组的处理方式

  • ​ 记录数组一共有几行几列,有多少个不同值

  • ​ 把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模

  import java.util.Arrays;
  /***
   * 稀疏数组
   * 
   * 
   * |  原数组行数  |  原数组列数  | 原数组有效数值个数
   * |------------|-------------|-------------
   * |有效值1所在行 | 有效值1所在列 |  有效值1的值
   * |有效值2所在行 | 有效值2所在列 |  有效值2的值
   * |有效值3所在行 | 有效值3所在列 |  有效值3的值
   * |有效值4所在行 | 有效值4所在列 |  有效值4的值
   * |有效值5所在行 | 有效值5所在列 |  有效值5的值
   * 
   */
  public class Exercise {
      public static void main(String[] args) {
          int[][] array = new int[10][11];
          array[8][8] = -6;
          array[2][9] = 5;
          array[6][2] = 18;
          array[7][3] = 8;
          array[9][2] = 3;
          array[4][1] = 6;
  
          System.out.println("原数组");
          printArray(array);
  
          int[][] array1 = compressArray(array);
          System.out.println("压缩后的数组");
          printArray(array1);
  
          int[][] array2 =  uncompressArray(array1);
          System.out.println("解压后的数组");
          printArray(array2);
  
      }
  
      public static int[][] compressArray(int[][] a) {
          //获取原数组有效数值的个数
          int sum = 0;
          for (int i = 0; i < a.length; i++) {
              for (int j = 0; j < a[0].length; j++) {
                  if (a[i][j] != 0) {
                      sum++;
                  }
              }
          }
          int[][] array = new int[sum + 1][3];
          array[0][0] = a.length;
          array[0][1] = a[0].length;
          array[0][2] = sum;
          int k = 1;
          for (int i = 0; i < a.length; i++) {
              for (int j = 0; j < a[0].length; j++) {
                  if (a[i][j] != 0) {
                      array[k][0] = i;
                      array[k][1] = j;
                      array[k][2] = a[i][j];
                      k++;
                  }
  
              }
          }
          return array;
      }
  
      public static int[][] uncompressArray(int[][] a) {
          int[][] array = new int[a[0][0]][a[0][1]];
          int k = 1 ;
          for (int i = 1; i <a.length ; i++) {
              array[a[i][0]][a[i][1]] = a[i][2];
          }
          return array;
      }
      public static void printArray(int[][] a) {
          for (int i = 0; i < a.length; i++) {
              for (int j = 0; j < a[0].length; j++) {
                  System.out.print(a[i][j] + "\t");
              }
              System.out.println();
          }
      }
  }
  
  

练习题

1)找出数组最小值

​ 首先创建一个长度是5的数组,并填充随机数,通过for循环,遍历数组,找出最小的一个值出来。

import java.util.Arrays;
/***
 *求最小值
 */
public class Exercise {
    public static void main(String[] args) {
        int[] array = new int[5];
        int min = 0;
        array[0] = (int) (Math.random() * 100);
        array[1] = (int) (Math.random() * 100);
        array[2] = (int) (Math.random() * 100);
        array[3] = (int) (Math.random() * 100);
        array[4] = (int) (Math.random() * 100);
        min = array[0];
        for (int i = 0; i < array.length; i++) {
            if(min > array[i]){
                min = array[i];
            }
            System.out.print(array[i]+"\t");
        }
        System.out.println();
        System.out.println("最小值为:"+min);
    }
}
2)反转数组

​ 首先创建一个长度是5的数组,并填充随机数,使用for循环或者while循环,对这个数组实现反转效果

import java.util.Arrays;
/***
 *反转数组
 */
public class Exercise {
    public static void main(String[] args) {
        int[] array = new int[5];
        int temp;
        array[0] = (int) (Math.random() * 100);
        array[1] = (int) (Math.random() * 100);
        array[2] = (int) (Math.random() * 100);
        array[3] = (int) (Math.random() * 100);
        array[4] = (int) (Math.random() * 100);
        System.out.println("原数组:"+ Arrays.toString(array));
        for (int i = 0; i < array.length/2; i++) {
            temp = array[i];
            array[i] = array[array.length - 1 - i];
            array[array.length - 1 - i] = temp;
        }
        System.out.println("反转数组:"+ Arrays.toString(array));
    }
}
3)数组排序

​ 首先创建一个长度是5的数组,并填充随机数,首先用选择法正排序,然后再对其使用冒泡法倒排序

​ 如上!

4)找出数组最大值

​ 首先创建一个长度是5的数组,并填充随机数,用增强型for循环找出最大的那个数

​ 和最小值的一样,大于号变小于号

5)合并数组

​ 首先准备两个数组,他俩的长度是5-10之间的随机数,并使用随机数初始化这两个数组,然后准备第三个数组,第三个数组的长度是前两个的和,通过System.arraycopy 把前两个数组合并到第三个数组中

import java.util.Arrays;
/***
 * 合并数组
 *使用System.arraycopy复制两个数组到新的数组
 */
public class Exercise {
    public static void main(String[] args) {
        int[] array = new int[5];
        int[] array1 = new int[10];

        for (int i = 0; i < array.length; i++) {
            array[i] = (int) (Math.random() * 100);
        }
        for (int i = 0; i < array1.length; i++) {
            array1[i] = (int) (Math.random() * 100);
        }

        int[] array2 = new int[array.length+array1.length];

        System.out.println("array  >>>>"+Arrays.toString(array));
        System.out.println("array1 >>>>"+Arrays.toString(array1));
        System.arraycopy(array,0,array2,0,array.length);
        System.arraycopy(array1,0,array2,array.length,array1.length);
        System.out.print("array2 >>>>"+Arrays.toString(array2));
    }
}
6)二维数组最大值

​ 定义一个5X5的二维数组。 然后使用随机数填充该二维数组。找出这个二维数组里,最大的那个值,并打印出其二维坐标

import java.util.Arrays;
/***
 * 二维数组最大值
 */
public class Exercise {
    public static void main(String[] args) {
        int[][] array = new int[5][5];
        int[] max = new int[3]; //存储最大值和坐标
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[0].length; j++) {
                array[i][j] = (int) (Math.random() * 100);
                System.out.print(array[i][j]+"\t");
            }
            System.out.println();
        }
        max[2] =  array[0][0];
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[0].length; j++) {
                if(array[i][j] > max[2]){
                    max[0] = i;
                    max[1] = j;
                    max[2] =  array[i][j];
                }
            }
        }
        System.out.println("最大值为:"+max[2]+"坐标为:"+max[0]+","+max[1]);
    }
}
7)二维数组排序

​ 首先定义一个5X8的二维数组,然后使用随机数填充满。借助Arrays的方法对二维数组进行排序。

import java.util.Arrays;
/***
 * 二维数组排序
 */
public class Exercise {
    public static void main(String[] args) {
        int[][] array = new int[10][5];
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[0].length; j++) {
                array[i][j] = (int) (Math.random() * 100);
                System.out.print(array[i][j]+"\t");
            }
            System.out.println();
        }
        //将生成的二维数组变成一维数组
        int[] a = new int[array.length*array[0].length];
        for (int i = 0; i < array.length; i++) {
            System.arraycopy(array[i],0,a,array[i].length*i,array[i].length);
        }
        Arrays.sort(a);
        System.out.println(Arrays.toString(a));
        //将排好序的一维数组写入二维数组中
        int k = 0;
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[0].length; j++) {
                array[i][j] = a[k];
                k++;
                System.out.print(array[i][j]+"\t");
            }
            System.out.println();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值