JavaSE--数组

JavaSE–数组

一、数组定义

变量空间是可以存放数据的,但是每一个变量空间只能存放一个数据。

1、数组的概念

数组是同一种类型数据的集合;即能够存放多个相同类型的数据的容器。

2、数组的定义方式

数组是存放多个数据的容器,Java中需要使用new关键字来创建容器,在创建容器时也要明确容器的大小,即容器中存放数据个数。有以下格式:

元素类型[] 数组名 = new 元素类型[元素个数或数组长度];

int[] arr = new int[3];//通过new关键字创建了一个长度为3,元素类型是int的数组实体。

3、数组用途

数组可以存储多个数据,而且可以对数据进行编号,从0开始。操作元素完成可以通过编号(索引)完成。

int[] arr = new int[3];
arr[0] = 3; //给数组编号(角标)为0的空间中存放int类型的常量值3
System.out.println(arr[1]);//输出数组编号为1空间中的值。

二、数组内存详解

1、java内存的分配

java内存分配:栈、堆、寄存器、常量池、静态域。

栈内存:存储局部变量,只要在方法中定义的都是局部变量。一旦声明周期结束,变量就会结束。

堆内存:存储都是实体(对象),每一个实体都有一个首地址,就是在内存中存储的位置。堆内存的变量都有初始化。

方法体中引用变量和基本变量都在栈上,其他都在堆中。

局部变量的引用型:会把对象存在堆中,而把引用存在栈中。

2、数组内存分配

int[] arr = new int[3];// 定义数组arr 指向 new 开辟的新数组地址
arr = null;// 定义数组arr 指向 null

在这里插入图片描述

说明:

  1. 程序执行main方法时,遇见new int[3]会在堆内存中开辟新空间,并给其分配一个地址(假设 0x34
  2. 数组各个空间都有默认的 编号角标或索引),将编号中对应的数据根据数据类型完成初始化
  3. 数组创建成功,将数组的地址赋值给arr,让arr指向中内存。
  4. 程序继续进行,将arr的指引赋值为null,即arr不再指向数组实体
  5. 这是堆中的数组会被标记成垃圾,等待垃圾回收站回收GC释放堆中资源。
public class Demo08 {
    public static void main(String[] args) {
        int[] arr = new int[4];// 1.定义数组 数组编号称为角标 从0开始的
        // 2.数组赋值
        arr[0] = 34;// 给第一个元素赋值
        arr[1] = 18;// 给第二个元素赋值
        arr[2] = 57;// 给第三个元素赋值
        System.out.println("数组arr的第二个元素是:"+arr[1]);
        System.out.println(arr);// 数组arr对应在堆中的地址信息。
        System.out.println("数组arr的第二个元素是:"+arr[3]);

        char chas[] = new char[3];
        System.out.println("chas[0]"+chas[0]);// 0
        System.out.println(chas[0]==0);// 0对应的字符

        boolean flags[] = new boolean[2];
        System.out.println("flags[0]"+flags[0]);// false

        String strs[] = new String[4];
        System.out.println("strs[0]"+strs[0]);// null
    }
}

3、数组常见问题

3.1、数组角标越界异常

public class Demo10 {
    public static void main(String[] args) {
        int arr[] = new int[3];
        System.out.println(arr[3]);
    }
}

在这里插入图片描述

3.2、数组空指针异常

public class Demo10 {
    public static void main(String[] args) {
        int arr[] = new int[3];
        //System.out.println(arr[3]);
        arr = null;
        System.out.println(arr[3]);
    }
}

在这里插入图片描述

三、数组应用

1、数组另一种定义格式

元素类型 数组名[] = new 元素类型[]{元素1,元素2,....元素n};
元素类型 数组名[] = {元素1,元素2,....元素n};

2、遍历数组

从角标0开始,主键递增的方位角标对应的每一位元素。

public class Demo12 {
    public static void main(String[] args) {
        int nums[] = {12,5,87,14,26};// 角标:0 1 2 3 4
        for (int i = 0;i<5;i++){
            System.out.println(nums[i]);
        }
        // Arrays.toString 快速打印数组内容 会打印 []
        System.out.println(Arrays.toString(nums));
    }
}

但是如果数组的内容异常庞大,这时候就需要确定数组的大小

// 数组对象的length属性存储了数组长度的信息。
System.out.println("nums数组的大小为:"+nums.length);
nums = new int[]{12,5,87,14,26,77,59,31,7,60,233,1514};
int arr_length = nums.length;
for (int i =0;i<arr_length;i++){
    System.out.println(nums[i]);
}

3、数组求和

需求:求数组中所有元素的和
思路:
  1. 需要定义个功能,用来求数组中所有元素的和值
  2. 定义功能,必须搞清楚两个明确。
    • 明确1:有返回结果,即所求的和值,和值类型int
    • 明确2:有未知参数参与。需要求和的数组,数组需要调用者传递给此功能。
步骤:
  1. 定义变量记录
  2. 通过循环对数组进行遍历。
public class Demo01 {
    public static int getSum(int []nums){
        int res = 0;// 求和结果
        int length = nums.length;// 获取长度
        for (int i =0;i<length;i++){
            res += nums[i];
        }
        return res;
    }

    // 数据类型... 形式参数 可变长度参数 就是数组
    public static int getSum1(int... nums){
        int res = 0;// 求和结果
        int length = nums.length;// 获取长度
        for (int i =0;i<length;i++){
            res += nums[i];
        }
        return res;
    }

    public static void main(String[] args) {
        int nums[] = {23,17,40,20};
        int sum = getSum(nums);
        System.out.println("数组的求和结果:"+sum);
    }
}

4、数组求最值

需求:获取多个整数中最大值。

思路:

  1. 数据多了为了便于操作,先存储起来。需要容器,用数组
  2. 多个数据需要进行比较。每次都有***较大***的数,需要记录下来和***下一个***数比较。
  3. 将数组中的元素都比一遍。最后,就获取到最大值

步骤:

  1. 接收欲求最大值的数组
  2. 定义一个变量记录住较大的数。
  3. 对数组进行遍历。让元素和较大的值进行比较。如果元素大于较大的数,用变量记录该元素。
  4. 遍历完成后,变量中记录就是最大值
public class Demo02 {
    /**
     * 求数组最大值
     * @param nums
     * @return
     */
    public static int getMax(int nums[]){
        int max = nums[0];// 默认最大值为第一个元素
        for (int i = 1;i<nums.length;i++){// 遍历数组的每一位
            if (max<nums[i]){// 判断当前为是否比max大
                max = nums[i];// 用大值替换max值
            }
        }
        return max;
    }

    public static int getMaxIndex(int nums[]){
        int max = 0;// 默认最大值为第一个元素的角标
        for (int i = 1;i<nums.length;i++){// 遍历数组的每一位
            if (nums[max]<nums[i]){// 判断当前为是否比max大
                max = i;// 用大值的角标替换max值的角标
            }
        }
        return nums[max];
    }
    
    public static void main(String[] args) {
        int nums[] = {7,23,44,16,32,99,34,13};
        Arrays.sort(nums);
        //int max = getMaxIndex(nums);
        //System.out.println("最大值是:"+max);
        System.out.println(Arrays.toString(nums));
        System.out.println(nums[nums.length-1]);
    }
}

四、数组练习

1、将数组转成字符串

  • 需求:将数组中的数字编程字符串输出。如[12,22,13,18,15] 拼接后"1222131815"
  • 思路:简单的方式就是利用了字符串和任何数据相加都是相连接。+
  • 步骤
    • 明确1:结果是什么类型?字符串类型。
    • 明确2:参数有什么?一个 int 类型的数组。
    • 1、定义字符串变量存储以后拼接的结果。
    • 2、遍历数组。将每一个数组的元素字符串相连接。
    • 3、判断不是最后一个元素,后面连接逗号,是最后一个元素,后面不连接逗号。
    • 4、将连接后的字符串返回。
/**
 * 数组和字符串
 */
public class Demo03 {
    public static String getStr(int nums[]){
        String str = "[";// 开头
        for (int i =0 ;i<nums.length;i++){// 遍历每一位
            if (i == nums.length-1){
                str += nums[i];// 最后一位
            }else{
                str += nums[i]+", ";// 非最后一位,需要 ,和空格
            }
        }
        str += "]";// 结尾
        return str;
    }

    // 纯数字字符串转化为数组
    public static int[] getArr(String str){
        int str_length = str.length();// 获取字符串长度。
        int arr[] = new int[str_length];// 数组长度和字符长度保持一致
        for(int i = 0;i<str_length;i++){
            char c = str.charAt(i);// 截取每一位
            int num = Integer.parseInt(c+"");// 字符串类型转化为数字类型。
            arr[i] = num;// 每一位赋值
        }
        return arr;
    }

    public static void main(String[] args) {
        //int nums[] = {23,17,3,45,83};
        //String str = getStr(nums);
        //System.out.println(str);
        //System.out.println(Arrays.toString(nums));
        //字符串截取
		//String str1 = "java OOP";
		//System.out.println(str1.charAt(1));
        String str = "65778723617";
        int[] arr = getArr(str);
        System.out.println(getStr(arr));

        str = "65-778-7-23-61-7";
        String[] split = str.split("-");
        System.out.println(Arrays.toString(split));
    }
}

2、数组反转

需求:将数组中的数据进行反转,如[12,22,13,18,15] 反转后[15,18,13,22,12]

思路

  1. 需要定义数组反转的功能:

    明确1:函数运算的结果?void 类型或者 int[]

    明确2:参与运行的参数?一个,int[]数组。

  2. ***数组反转***就是将数组中的值进行位置互换。

    互换的条件是:

    • 0角标和length-1角标位置上的值互换。
    • 1角标和length-2角标位置上的值互换。
    • 以此类推。
  3. 互换到什么时候停止呢?只要头角标大于等于尾角标就停止。

  4. 怎么互换呢?互换就是交换两个空间中的值,可以使用第三方变量。(三元置换)

步骤:

  1. 定义功能,接收数组。
  2. 遍历数组,每遍历一次交换数组两个位置的上的值,start代表头角标,end代表尾角标
  3. 交换每次遍历的两个空间[start,end]中的数据。
class ArrayTest4 
{
	public static void main(String[] args) 
	{
		int[] arr = {12,22,13,18,15};
		printArray(arr); // 输出
		reverseArray(arr); // 反转
		printArray(arr);// 输出
	}
	//1、定义功能,接受数组
	public static void reverseArray(int[] arr)
	{
		//2、遍历数组,每遍历一次交换数组两个位置的上的值,
		//   start代表头角标,end代表尾角标
		for (int start = 0,end=arr.length-1;start<end ;start++,end-- )
		{
			//3、交换每次遍历的两个空间中的数据
			int temp = arr[start];
			arr[start] = arr[end];
			arr[end] = temp;
		}
	}
	//此功能为打印数组
	public static void printArray(int[] arr)
	{
		for (int i=0;i<arr.length ;i++ )
		{
			if(i!=arr.length-1)
				System.out.print(arr[i]+",");
			else
				System.out.println(arr[i]);
		}
	}
}

3、数组使用心得

数组容器的特点:1、固定长度 2、元素都有索引

什么时候使用容器:数据多了,必须先进行存储。然后进行操作。

什么时候使用数组:数据多,数据个数确定,而且数据与顺序有对应关系。在分析需求时确定:

  1. 需求中的数据是否有对应的有序编号?
  2. 需求中的数据是否需要有序的编号?如果有,就用数组存储。

4、查表法

需求1:根据用户输入的数据,显示对应的星期

思路

  1. 星期有多个,个数固定。
  2. 星期对应的有序编号。有序的编号就可以作为索引。所以可以使用数组这种结构进行存储。
  3. 定义一个功能。根据给定的数据获取对应的星期。
public static String getWeek(int num)
{
	if(num>7 || num<1) return num+"没有对应的星期";
    //throw new RuntimeExcpetion(num+"没有对应的星期");
	//定义一个数组,存储固定的星期数。这个称之为一个存储了对应关系的表。
	String[] weeks = {"","星期一","星期二","星期三","星期四","星期五","星期六","星期日"};
	//其实就是根据制定的索引在查表。
	return weeks[num];
}

什么是查表法:

查表法:数据之间存在对应关系。通过关系中一方查询另一方。当对应关系存在,但没有一方是有序编号时,使用另一个容器 map(集合框架时学习)。

需求2 : 十进制–>十六进制。

思路:在前面讲解时,使用的&15(0B1111)运算每次可以取出十进制的最低四位数值,并将其打印在控制台上,遇到了两个问题,数据顺序反。同时还会有打印出多个0。

***分析数据顺序反的原因***是&15运算要执行多次,每次都将运算结果直接打印在控制台,若将这些值直接存储在容器中,存完之后按照相反的顺序打印出来,那么看到的数据就是正确的。

/**	
解决方式:
	1、顺序反?每运算出一位,不要打印,先存储。需要容器。
    2、去除零?需要转换的数据会不断的右移,如果右移后剩余的二进制都是0,也就是没有有效位,就不需要进行&运算了。也就是不需要在往数组中存储了。
*/
class ArrayTest6 
{
	public static void main(String[] args) 
	{
		int num = 60;
		String str_hex = toHex(num);
		System.out.println(str_hex);
	}
	public static String toHex(int num)
	{
		//1,定义容器。存储的是字符,长度为8.一个整数最多8个16进制位。
		char[] chs = new char[8];
		//2,定义一个用于操作数组的索引。
		int index = chs.length;
		while(num!=0)
		{
			int temp = num & 15; // 和数字15的二进制进行'与'运算。确定对应的16进制每一位是否有值。
			if(temp > 9)
				chs[--index] = ((char)(temp-10+'A'));
			else
				chs[--index] = ((char)(temp+'0'));
			num = num >>> 4;// 无符号右移
		}
		System.out.println("index="+index);
		return "0x"+toString(chs,index);
	}
	//定义一个功能,将字符数组转成字符串。
	public static String toString(char[] arr,int index)
	{
		String temp = "";
		for(int x=index; x<arr.length; x++)
		{
			temp = temp + arr[x];
		}
		return temp;
	}
}

需求3:十进制–>十六进制(查表法)

思路:十进制转成十六进制的每一位都是十六进制元素中的某一个。十六进制的元素有很多固定个数。而且还有对应的编号。所以可以使用查表法!

class ArrayTest7 
{
	public static void main(String[] args) 
	{
		int num = 26;
		String str_hex = toHex(num);
		System.out.println("hex:"+str_hex);
	}
    
    // 转化
	public static String toHex(int num)
	{
		//1,建立表。
		char[] chs = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
		//2,创建临时容器。
		char[] arr = new char[8];
		//3,创建操作临时容器的角标。
		int index = arr.length;
		//4,通过循环对num进行& >>等运算。
		while(num!=0)
		{
			//5,对num进行&运算。
			int temp = num & 15;
			//6,根据&运算后的结果作为角标查表,获取对应的字符。并将字符存储到临时容器中。
			arr[--index] = chs[temp];
			//7,对num进行右移。
			num = num >>> 4;
		}
		return "0x"+toString(arr,index);
	}
	//定义一个功能,将字符数组转成字符串。
	public static String toString(char[] arr,int index)
	{
		String temp = "";
		for(int x=index; x<arr.length; x++)
		{
			temp = temp + arr[x];
		}
		return temp;
	}
}

五、数组排序

如何让数组中的值变的有序呢,比如从小到大,或者从大到小的排列。

1、选择排序

选择排序是排序中的一种。算法原则(从小到大排序):先用数组中第一个空间值和数组中剩余的其他空间值 依次做比较,在比较的过程有任何值比第一个空间值,就用第一个空间值当前这个空间值换位置,直到所有值第一个空间值全部比较完。第一个空间中就放着最小值。接着在使用数组第二个空间值和数组中剩下空间中值做比较,比较方式和前一次相同。以此类推,比较完成。

规律第一个空间剩余空间比一圈,第二个空间在和剩余空间比一圈,以此类推,到倒数第二个空间值和最后一个空间值比完,整个数组有有序了。正好符合了***外循环循环一次,内循环执行一圈***。即外循环控制每次到底使用哪个空间值和剩余空间比较,内循环提供剩余空间。

图解 :
在这里插入图片描述

public static void selectSort(int[] arr)
{
	for(int x=0 ;x<arr.length-1; x++)  //提供比较的空间角标
	{
		for(int y=x+1; y<arr.length; y++) //提供剩余空间的角标
		{
			if(arr[x]>arr[y])  //判断当前外循环角标位置上的值和内循环角标位置上的值
			{
				int temp = arr[x];
				arr[x] = arr[y];
				arr[y] = temp;
			}
		}
	}
}

2、冒泡排序

冒泡排序算法原理:这种算法和生活中常见的水中气泡的浮沉类似。

数组冒泡算法(从小到大):

  • 数字第一个空间值和第二个空间值比较,把较大的值存在第二个空间中,接着第二个空间值和第三个空间值作比较,较大的值存在第三个空间中,以此类推直到倒数第二个空间和倒数第一个空间比较,把较大值存放在最后一个空间中。
  • 由于最后一个空间已经是最大值了,那么第二轮算法和第一轮一样,只是最后一次比较是倒数第三个空间和倒数第二个空间比较。把较大的值存在倒数第二个空间中。
  • 以此类推。

在这里插入图片描述

/**
* 冒泡排序。
*/
public static void bubbleSort(int[] arr)
{
	for(int x=0; x<arr.length-1; x++)// 决定了比较范围。
	{
		for(int y=0; y<arr.length-1-x; y++)// 从0开始比较到指定范围,范围逐渐缩小。
		{
			if(arr[y]>arr[y+1])// 两两比较 升序
			{
				int temp = arr[y];
				arr[y] = arr[y+1];
				arr[y+1] = temp;
			}
		}
	}
}

六、数组查找

1、一般查找

从组中第一个空间开始查找,每取出一个空间值和待查找的数值做比较若相等,就返回当前角标;若数组遍历结束,没有找到相等的值,则返回-1

public static int searchKey(int[] arr,int key)
{
	//遍历查找。
	for(int x=0; x<arr.length; x++)
	{
		if(arr[x]==key) return x;// 找到就返回。
	}
	return -1;//-1,代表的是角标不存在的情况。
}

2、折半查找

折半查找,必须保证数组已经是有序的。

思路

  1. 通过角标先获取中间角标上元素。
  2. 让该元素和要找的数据比较。
  3. 如果要找的数大了,缩小范围,要找的范围应该是 中间的角标+1 = = = > ===> ===>尾角标 ; 如果要找的数小了,要找的范围 头角标 = = = > ===> ===>中间角标-1
  4. 不断如此重复,就可以找到元素对应的角标。
public static int binarySearch(int[] arr,int key)
{
	//1,定义三个变量,记录头角标,尾角标,中间角标。
	int max,min,mid;
	min = 0;// 中
	max = arr.length-1;// 大
	mid = (max+min)>>1;// 小  max+min /2
	while(arr[mid]!= key)// 遍历
	{
		if(key>arr[mid])
			min = mid + 1;
		else if(key<arr[mid])
			max = mid - 1;
		//判断元素是否存在。
		if(max<min)
			return -1;
		mid = (max+min)>>1;
	}
	return mid;
}

七、二维数组

二维数组,其实就是一个数组中又装了一个数组。

1、二维数组定义

int[][] arr = new int[3][2];

定义了名称为arr的二维数组, 二维数组中有3个一维数组,每一个一维数组中有2个元素, 一维数组的名称分别为arr[0], arr[1], arr[2]

arr[1][1] = 78;// 二维数组赋值
System.out.println(arr);// [[I@e6f7d2//二维数组实体 
System.out.println(arr[0]);// [I@3e0ebb//一维数组实体。
System.out.println(arr[0][0]);// 0 一维数组中的元素。

2、二维数组图解

在这里插入图片描述

3、二维数组的其他定义格式:

int[][] arr = new int[3][];// 定义一维数组为null的二维数组。

二维数组中有3个一维数组,每个一维数组都是默认初始化值null。

arr[0] = new int[3];
arr[1] = new int[1];
arr[2] = new int[2];
// 统一赋值

可以对这个三个一维数组分别进行初始化。

int[][] arr = new int[][]{{3,8,2},{2,7},{9,0,1,6}};

定义一个名称为arr的二维数组,二维数组中的有三个一维数组,每一个一维数组中具体元素也都已初始化。

  • 第一个一维数组 arr[0] = {3,8,2};
  • 第二个一维数组 arr[1] = {2,7};
  • 第三个一维数组 arr[2] = {9,0,1,6};
  • 第n个一维数组的长度表示方式:arr[n-1].length;

八、二维数组应用

1、二维数组求和

class Array2Demo 
{
	public static void main(String[] args) 
	{
		int[][] arr = {{3,8,2},{2,7},{9,0,1,6}};
		int sum = getSum(arr);
		System.out.println("sum="+sum);
	}
	// 求二位数组的和值
	public static int getSum(int[][] arr)
	{
		int sum = 0;
		for (int i=0;i<arr.length ;i++ )// 遍历二维数组每一个一维数组
		{
			for (int j=0;j<arr[i].length ;j++ )// 遍历一维数组的每一个元素
			{
				sum += arr[i][j];
			}
		}
		return sum;
	}
}

延伸学习

一、数学函数

Java在Math类中提供了许多实用方法,来计算常用的数学函数。

1、三角函数

在这里插入图片描述

sin、cos和tan的参数都是以弧度作为单位的角度。asin和atan的返回值是 -π/2 ~ π/2 的一个弧度值,acos的返回值在 0 ~ π 之间。相当于 π/180 弧度,90°相当于 π/2 弧度,30°相当于 π/6 弧度。

public class MathDemo {
    public static void main(String[] args) {
        // 获取系统π值(180°)
        double pie = Math.PI;
        double degrees = Math.toDegrees(pie / 2);
        System.out.println("度数是:" + degrees);// 90°
        double radians = Math.toRadians(30);
        System.out.println("弧度值是:" + radians);// π/6
        // sin值
        System.out.println(Math.sin(0));
        System.out.println(Math.sin(Math.toRadians(270)));
        System.out.println(Math.sin(pie / 6));
        System.out.println(Math.sin(pie / 2));
        // cos值
        System.out.println(Math.cos(0));
        System.out.println(Math.cos(pie / 6));
        System.out.println(Math.cos(pie / 2));
        // asin
        System.out.println(Math.asin(0.5));// π/6
        System.out.println(Math.acos(0.5));// π/3
        System.out.println(Math.atan(1.0));// π/4
    }
}

2、指数函数

在这里插入图片描述

public class MathDemo01 {
    public static void main(String[] args) {
        // 指数函数
        double e = Math.E;
        System.out.println("e = " + e);// 自然数e
        System.out.println(Math.exp(1));// e的1次方
        System.out.println(Math.log(e));// 以e为底,log值
        System.out.println(Math.log10(10));// 以10为底,log值
        System.out.println(Math.pow(2,3));// 2的3次方
        System.out.println(Math.pow(3,2));// 3的2次方
        System.out.println(Math.pow(4.5,2.5));// 4.5的2.5次方
        System.out.println(Math.sqrt(4));// 2的平方根
        System.out.println(Math.sqrt(10.5));// 10.5的平方根
    }
}

3、取整方法

在这里插入图片描述

public class MathDemo02 {
    public static void main(String[] args) {
        // ceil取整
        System.out.println(Math.ceil(2.1));
        System.out.println(Math.ceil(2.0));
        System.out.println(Math.ceil(-2.0));
        System.out.println(Math.ceil(-2.1));
        //  floor取整
        System.out.println(Math.floor(2.1));
        System.out.println(Math.floor(2.0));
        System.out.println(Math.floor(-2.0));
        System.out.println(Math.floor(-2.1));
        // rint取整
        System.out.println(Math.rint(2.1));
        System.out.println(Math.rint(-2.0));
        System.out.println(Math.rint(-2.1));
        System.out.println(Math.rint(2.5));
        System.out.println(Math.rint(4.5));
        System.out.println(Math.rint(-2.5));
        // round取整
        System.out.println(Math.round(2.6f));
        System.out.println(Math.round(2.0));
        System.out.println(Math.round(-2.0f));
        System.out.println(Math.round(-2.6));
        System.out.println(Math.round(-2.4));
    }
}

4、min、 max、 abs方法

minmax 方法用于返回两个数*(int、long、float和double型)*的最小值最大值。例如:max(4.4,5.0)返回5.0。而min(3,2)返回2

abs方法 返回返回一个数*(int、long、float和double型)*的绝对值

public class MathDemo03 {
    public static void main(String[] args) {
        // max、min、abs
        System.out.println(Math.max(2,3));
        System.out.println(Math.max(2.5,3));
        System.out.println(Math.min(2.5,4.6));
        System.out.println(Math.abs(-2));
        System.out.println(Math.abs(-2.1));
    }
}

5、random方法

0.0 <= Math.random < 1.0: 范围在 0.01.0 之间,取不到 1.0

6、计算三角形角度

根据一个三角形的三个边,计算构成三个角的角度。
在这里插入图片描述

public class ComputerAngles {

    public static void main(String[] args) {
        // 引入Scanner类,获取输入信息。
        Scanner sc = new Scanner(System.in);
        // 获取坐标
        System.out.println("输入三个点坐标");
        double x1 = sc.nextDouble();
        double y1 = sc.nextDouble();
        double x2 = sc.nextDouble();
        double y2 = sc.nextDouble();
        double x3 = sc.nextDouble();
        double y3 = sc.nextDouble();
        // 计算三条边 两点之间距离公式
        double a = Math.sqrt((x2 - x3) * (x2 - x3) + (y2 - y3) * (y2 - y3));
        double b = Math.sqrt((x1 - x3) * (x1 - x3) + (y1 - y3) * (y1 - y3));
        double c = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
        // 计算三角度数
        double A = Math.toDegrees(Math.acos((a * a - b * b - c * c) / (-2 * b * c)));
        double B = Math.toDegrees(Math.acos((b * b - a * a - c * c) / (-2 * a * c)));
        double C = Math.toDegrees(Math.acos((c * c - b * b - a * a) / (-2 * a * b)));
        // 输出
        System.out.println("三个角分别是:" + Math.round(A * 100) / 100.0 + " " +
                Math.round(B * 100) / 100.0 + " " +
                Math.round(C * 100) / 100.0);
    }
}

二、字符以及操作

1、字符

字符数据类型表示单个字符。

char letter = 'A';// 将 字符A 赋值给char类型的letter
char numChar = '4';// 将 数字字符A 赋值给char类型的numChar

注意:字符串直接量必须包括在双引号【""】中,而字符直接量是括在单引号【''】中的单个字符。因此"A"是一个字符串,而'A'是一个字符

2、Unicode 和 ASCII 码

计算机内部使用二进制数。一个字符在计算机中以 0 和 **1 ** 构成的序列的形式来存储的。将字符映射到它的二进制形式的过程称为 编码(encoding)。字符有多种不同的编码方式,编码表(encoding scheme)定义该如何编码每个字符。

Unicode 一开始被设定为16位的字符编码。基本数据类型 char 试图提供一种能存放任意字符的简单数据类型来利用这个设计。但是16位不足就扩展为 1 112 064***个字符。称之为***补充字符 (supplementary character)。

大多数计算机采用ASCII编码(美国标准信息交换码),它是所有大小字母、数字、标点符号和控制字符的 8 位编码表。Unicode 包含 ASCII 码。

在这里插入图片描述

char letter = 'A';
char letter = '\u0041'; 
//都是将字符A赋值给letter

注意:自增 和 自减操作符也可以运用在 char 类型变量上,得到当前字符之前和之后的 Unicode 字符。

char ch = 'a';
System.out.println(++ch);

3、特殊字符的转义序列

补充多个转义字符。

在这里插入图片描述

反斜杠 \ 被称为转义字符。它是一个特殊字符。要显示这个字符,需要转义序列 \\

4、字符和数字转化

char类型数据可以转化成任意一种数值类型,反之亦然。将整个整数转化成 char 型数据时,只用到该数据的低十六位。其余部分忽略。

char ch = (char)0xAB0041;// 低16位的0041存储
System.out.println(ch);// 把A存储

要将一个 浮点值 转换成 char 型时,首先将 浮点值 转换成 int 型,然后将整个整型值转换成 char 型。

char ch = (char)65.25;// 其实就是把65存储进入
System.out.println(ch);// 把A存储

当一个char型数据转换成数值型时,这个字符的Unicode码就被转换成某个特定的数值类型。

int i = (int)'A';// A的Unicode存储到i中。
System.out.println(i);// 把A存储

如果转换结果适用于目标变量,就使用隐式变量;否则,必须使用强制类型转换方式。a的ASCII 十进制码是97在一个字节范围内。Unicode码 \uFFF4超过一个字节。

byte b = 'a';
int i = 'a';
byte b = (byte)'\uFFF4';

0 ~ FFFF 的任何一个十六进制正整数都可以隐式地转成字符型数据。而超过此范围的都需要强制类型转化为char型。

5、比较和字符方法

两个字符可以使用关系操作符进行比较,就如同比较两个数字一样。这是通过比较两个字符的Unicode 值实现的。

 char ch = 'A';// 任意
if(ch >='A' && ch <='Z') System.out.println("大写字母");
else if(ch >='a' && ch <='z') System.out.println("小写字母");
else if(ch >='0' && ch <='9') System.out.println("数字");

字符char有自己的封装类型Character,封装了很多方法以便我们使用。

在这里插入图片描述

public class CharDemo01 {
    public static void main(String[] args) {
        // 是否是数字
        boolean isNumber = Character.isDigit('a');
        // 是否是字母
        boolean isCode = Character.isLetter('a');
        // 是否是字母或数字
        boolean letterOrDigit = Character.isLetterOrDigit('a');
        // 是否是小写字符
        boolean lowerCase = Character.isLowerCase('a');
        // 是否是大写字符
        boolean upperCase = Character.isUpperCase('a');
        // 转小写
        char lowerCase1 = Character.toLowerCase('a');
        // 转大写
        char upperCase1 = Character.toUpperCase('a');
    }
}

三、String类型

String 字符串其实就是一个字符序列。

在这里插入图片描述

1、获取长度

调用 length() 方法获取长度。具体代码如下:

String message = "This is a long String.";
System.out.println(message.length());// 获取字符串长度

使用一个字符串的时候,往往知道它的字面值常量的。为了方便,Java允许再不创建新的字符串的情况下,使用字符串直接使用字面值常量。所以,“This is a long String.”.length() 是正确的。而且 “”.length() 的值为0,""不是null。

2、截取字符

方法 s.charAt(index) 可用于提取字符串s中某个指定的字符,其下标取值在[0 ,s.length() - 1]。
在这里插入图片描述

警告:如果访问的长度超过了s.length() - 1,就会造成一种常见的程序设计错误,访问越界错误,发生:StringIndexOutOfBoundsException()异常。

3、字符串转化

方法toLowerCase()返回一个新字符串,其中所有字母都小写;方法toUpperCase()返回一个新字符串,其中所有字母都大写。

"WelCome".toLowerCase();// welcome
"WelCome".toUpperCase();// WELCOME

方法 trim 通过删除字符串两端的空白字符返回一个新字符串。字符 ’ ’ 、\t、\f、\r、\n都被称为空白字符:

"\t Good Night \n".trim();// "Good Night"

4、字符串比较

在这里插入图片描述

除了之前的 equals() 方法以外,还可以使用 compareTo()方法来比较两个字符串。

s1.compareTo(s2);// 如果 s1 和 s2 相等,那么返回0。如果按照字典顺序(Unicode码顺序)s1 < s2 ,那么该方法返回值小于0;如果s1 > s2 ,那么该方法返回值大于0。

实际上比较每一位字符之间的距离和。

5、获取子字符串

方法 s.charAt(index) 可用于提取字符串s中某个指定的字符,也可以使用 substring 获取一个字符串。

String message = "Welcome to Java";
String message = message.substring(0,11) + "HTML";
// "Welcome to Java" 变成了 "Welcome to HTML"

在这里插入图片描述

6、字符串和数字转化

可以将数值型字符串转化为数字,要将字符串转化为int,使用Integer的parseInt方法;

int intValue = Integer.parseInt(intString);// intString 数值型字符串,例如"123"。

其它数值就采取同样的方法来转化,如:Double.parseDouble(doubleString) 转化一个 数值型字符串 如:“4.13”。

而数字转化为字符串,只需要简单的字符串的连接符就行;

String s = number + "";

四、格式化输出

System.out.printf(format,item1,item2.....item n);format:一个字符串和字符串格式标识符构成的字符串。

格式标识符 指定每个条目应该如何显示。这里条目就是数值、字符、布尔值或字符串。简单的格式标识符是以(%)开头的转换码。

在这里插入图片描述

在这里插入图片描述

条目与格式标识符必须在类型上严格匹配。对应于格式标识符 %f 或 %e 的条目必须是浮点型

使用符号%来标记格式标识符,要在格式字符串里输出直接量%,需要使用%%。

默认情况下输出右对齐,可以在格式标识符中放一个负号(-),表示输出是左对齐。

public class FormatDemo01 {
    public static void main(String[] args) {
        System.out.printf("%-10s%-10s%-10s%-10s%-10s\n","Degrees","Radians","Sine"
        ,"Cosine","Tangent");

        int degrees = 30;
        double radians = Math.toRadians(degrees);
        System.out.printf("%-10d%-10.4f%-10.4f%-10.4f%-10.4f\n",degrees,radians,
                Math.sin(radians),Math.cos(radians),Math.tan(radians));

        degrees = 60;
        radians = Math.toRadians(degrees);
        System.out.printf("%-10d%-10.4f%-10.4f%-10.4f%-10.4f\n",degrees,radians,
                Math.sin(radians),Math.cos(radians),Math.tan(radians));
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值