Java入门第二节
一.Java中的字符串String
Java String 类 | 菜鸟教程 (runoob.com)
1.c语言中定义字符串
char str_1[6] = {'h','e','l','l','o','\0'};
char str_2[] = "world";
2.Java定义字符串与其用法
// 字符串的定义
String str_1 = "hello";
String str_2 = "hello";
// 字符串扩展
String str_3 = new String("hello world");
String str_4 = new String("hello world");
// 输出一下结果是否相等
System.out.println(str_1==str_2);
System.out.println(str_3==str_4);
// 输出后第一组为true,第二组为false
// 原因要从内存方面分析,我们后面讲
常用方法与构造Java—String-CSDN博客
3.C字符串结尾有\0,为什么java没有
一.C语言种的字符串是怎样的?
C语言中没有专门的字符串变量,通常用一个字符数组来存放一个字符串;
字符串本质上就是以'\0'作为结尾的特殊字符数组;
因此当把一个字符串存入一个数组时,也把结束符 '\0'存入数组,并以此作为该字符串是否结束的标志;
二.为什么Java里没有/0?
严格控制字符串,防止内存泄漏,这是Java为了保护程序以及开发者友好,强制并自动为我们加了'\0'
二.数据类型转换
Java 基本数据类型 | 菜鸟教程 (runoob.com)
(1).自动类型转换
整型、实型(常量)、字符型数据可以混合运算。运算中,不同类型的数据先转化为同一类型,然后进行运算;
转换从低级到高级:
byte,short,char—> int —> long—> float —> double
byte one = 44;
int two = one;
System.out.println("two = " + two);
小品《主角与配角》象征性代表了int取代char的地位
数据类型转换必须满足如下规则:
1. 不能对boolean类型进行类型转换。
2. 不能把对象类型转换成不相关类的对象。
3. 在把容量大的类型转换为容量小的类型时必须使用强制类型转换。
int str_1 = 10;
byte str_2 = (byte) str_1;
System.out.println("str_2 = " + str_2);
4. 转换过程中可能导致溢出或损失精度,例
int str_1 = 44444;
byte str_2 = (byte) str_1;
// 输出后会导致精度溢出,结果为-100
System.out.println("str_2 = " + str_2);
// 数字之间可以用下划线隔开
byte one = 20;
int two = 10_0000_0000;
int three = one * two;
// 输出时,你会发现输出结果不对,因为默认是int导致精度溢出
System.out.println("three = " + three);
// 所有我们需要,把默认值更改为long
long four = one * (long)two;
System.out.println("four = " + four);
5. 浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入
double str_1 = 333.111;
int str_2 = (int)str_1;
// 输出后得到333
System.out.println("str_2 = " + str_2);
(2).强制类型转换
1. 条件是转换的数据类型必须是兼容的;
(3).隐含强制类型转换
1.整数的默认类型是 int。
2.小数默认是 double 类型浮点型,在定义 float 类型时必须在数字后面跟上 F 或者 f。
// byte 数据类型,取值范围是-128~128
byte one = 110;
byte two = 100;
// 输出后值为210,没有溢出。
// 可以看出相加过程中,发生了隐含强制类型转换,强制转换成了int类型
System.out.println((one + two));
三.import导包和API文档
API文档:概述 (Java 平台 SE 8 ) (oracle.com)
API中文文档:Java17中文文档 - API参考文档 - 全栈行动派 (qzxdp.cn)
1.jdk开发包里已经写好了许多函数,与C语言里的标准库一样;
2.import和C中的#include一样,导入一些自带的方法,使用同一个package下的包不需要import,java.lang.*是java默认自带的包不需要导入,导包时要保持正确,不然无法使用;
四.Java中方法
1.什么是方法,其实就是函数 2.方法的定义 public static void main(String[] args) {} 修饰词 返回值类型 方法名 参数类型 函数体
public class Drop {
public static void main(String[] args) {
// 比大小
System.out.println("最大值 = "+ max(6,9));
}
public static int max(int x,int y) {
int z = 0;
if (x == y) {
System.out.println("相等");
// 终止方法
return 0;
}
return (x > y)? x: y;
}
}
3.方法重载
public class Drop {
public static void main(String[] args) {
//快捷方式
//1.psvm自动打印方法
//方法的重载,一.方法名相同,二.参数个数或参数类型不同;
//方法重载非法强大以至于java底层的源码都是这样写的;
//例子如下
System.out.println("sum(3,3) = " + sum(3,3));
}
public static int sum(int x,int y){
return x+y;
}
public static double sum(double x,double y){
return x+y;
}
public static int sum(int x,int y,int z){
return x+y+z;
}
public static void sum(double x,int y){
}
}
4.方法调用分为两种:
一.值传递(Java属于这种)
值传递
(pass by value)是指在调用函数时将实际参数 复制
一份传递到函数中,而并不是将这个值直接传递给函数。
public static void main(String[] args) {
int value = 10;
setValue(value);
System.out.println("调用后:"+ value);
}
public static void setValue(int value) {
value = 2 * value;
System.out.println("调用时:" + value);
}
// 调用时:20,调用后:10
说明:value
的值并没有因为调用了 setValue()
方法,而发生改变也就是说,我们验证了 java 中的 基本类型 是采用值传递的方式的。
public static void main(String[] args) {
String value = "hello";
setValue(value);
System.out.println("调用后:"+ value);
}
public static void setValue(String value) {
value = value + "123";
System.out.println("调用时:" + value);
}
// 调用时:hello123,调用后:hello
说明:value
的值并没有因为调用了 setValue()
方法,而发生改变那么,我们也验证了 java 中的 引用类型
是采用值传递的方式的。
二.引用传递,代码看不懂没关系后面会讲
引用传递
(pass by reference)是指在调用函数时将实际参数的地址直接传递到函数中,而传递过来的地址还是与之前的地址指向同一个值,那么要是修改了这个参数,就会影响这个值的改变。
public class Dogs {
public static void main(String[] args) {
Perosn perosn = new Perosn();
System.out.println(perosn.name);// null
Dogs.change(perosn);
System.out.println(perosn.name);// fuck
}
// 返回值类型为空
public static void change(Perosn perosn){
// perosn是一个对象,指向 Perosn perosn = new Perosn();
perosn.name = "fuck";
}
}
// 另一个类
class Perosn{
String name;// null
}
5.命令行传参
public class Drop {
public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
System.out.println("age["+ i +"]"+ args[i]);
}
}
}
6.可变参数
public class Drop {
public static void main(String[] args) {
// 不确定参数的个数时使用,...
text(3,1,55,6,6,2,7,5,44);
}
public static void text(int...i) {
for (int j = 0; j < i.length; j++) {
System.out.println(i[j]);
}
}
}
7.递归
public class Drop {
public static void main(String[] args) {
// 递归就是自己调用自己
// 条件1.递归要有头,没有头会陷入死循环
man();
}
public static void man() {
man();
}
}
public class Drop {
public static void main(String[] args) {
// 条件2.什么时候需要调用自身方法
// 例子:求5的阶乘等于多少
System.out.println("5的阶乘等于:"+ f(5));
}
public static int f(int n) {
if (1 == n){
return 1;
}else {
// 首先求出所有f(n)的结果,然后倒推回来,最后得出结果
return n * f(n-1);
}
}
}
// 不能用递归就不用递归,递归没有头造成内存崩溃
// 递归会占用大量的空间内存
五.Java中的数组
1.java的内存分析
一.堆:
存放new的对象和数组,可以被所有的线程共享,不会存放别的对象引用
二.栈
存放基本变量类型(包括这个基本类型的具体数值)
引用对象的变量(存放这个引用在堆里面的具体地址)
三.方法区
可以被所有的线程共享
包含了所有的class和static变量
2.数组的定义与其用法
public class Main {
public static void main(String[] args) {
//快捷方式
//1.sovtu直接生成输入语句
//2.fori直接生成for循环
//3.foreach直接生成增强for循环
//静态数组
//一.定义数组
//方法1.分配方式
int[] str_1 = new int[5];//new等于开辟一个新的空间
str_1[0] = 1;
str_1[1] = 2;
//方法2.初始化
int[] str_2 = {1,5,6,7,33,33,335};
System.out.println("str_1[1] = " + str_1[1]);
//二.数组中的length的用带括号,但变量中的length要带括号
//1.输出语句中
System.out.println("str_2.length = " + str_2.length);
//2.for循环中
for (int j = 0; j < str_2.length; j++) {
System.out.println(str_2[j]);
}
//三.增强for循环
for (int e:str_1) {
System.out.println(e);
}//int为str_1中每一个元素的类型,e为增强for循环名,str_1为数组名
//四.处理数组
//1.计算所有元素的总和
int sum = 0;
for (int w:str_2) {
sum += w;
}System.out.println("str_2和 = " + sum);
//2.查找最大元素
int max = str_2[0];
for (int q:str_2) {
if (q > max){
max = q;
}}System.out.println("max = " + max);
//五.数组作为函数的参数
int[] str_3 = {3,5,6,8,1};
man(str_3);
}
public static void man(int[] arr){
for (int i:arr) {
System.out.println(i);
}
//六.数组作为函数的返回值
int[] str_4 = {3,5,6,4,};
System.out.println("str_4和 = " + data(str_4));
}
public static int data(int[] arr){
int sum = 0;
for (int i:arr) {
sum += i;
}
return sum;
}
public static void drop(String[] ages){
//七.多维数组,以二维数组为例
int[][] str_5 = new int[2][2];
str_5[0][0] = 6;
System.out.println("str_5[0][0] = " + str_5[0][0]);
}
}
import java.util.Arrays;
public class Date {
public static void main(String[] args) {
//八.Arrays类,java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的。
int[] str_1 = {3,5,1,6,4,11,77,515};
//1.给数组赋值:通过 fill 方法,也叫填充数组
//例子1,将数组中的所有元素初始化为相同的值
int[] arr_3 = new int[5];
Arrays.fill(arr_3,10);
System.out.println(Arrays.toString(arr_3));
//例子2,将数组中的所有元素初始化为相同的字符串
String[] arr_4 = new String[3];
Arrays.fill(arr_4,"fuck");
System.out.println(Arrays.toString(arr_4));
//2.对数组排序:通过 sort 方法,按升序。同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。
Arrays.sort(str_1);
for (int i:str_1) {
System.out.println("str_1从小到大 = " + i);
}
//3.比较数组:通过 equals 方法比较数组中元素值是否相等。如果两个数组以相同顺序包含相同的元素,则两个数组是相等的。
// 同样的方法适用于所有的其他基本数据类型(Byte,short,Int等)。
// 返回是boolean所以我们要用boolean去接收
int[] arr_1 = {1,2,3};
int[] arr_2 = {1,2,3};
boolean b = Arrays.equals(arr_1,arr_2);
System.out.println("b = " + b);
//4.查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作。
//有的话会返回在排序的第几个,没有的话返回一个负的插入点
//已经排序完成,见2
int fuck_index = Arrays.binarySearch(str_1,777);
System.out.println("fuck_index = " + fuck_index);
}
}
import java.util.Arrays;
public class Mani {
public static void main(String[] args) {
// 冒泡排序无疑是最为出名的排序算法之一
// 1.比较数组中,两个相邻的元素,如果第一个数比第二个数大,我们就交换它们的位置
// 2.每一次比较,都会产生出一个最大,后最小的数
// 3.下一轮可以少一次排序
// 4.依次循环,直到结束
int[] one = {4, 1, 5, 6, 55, 66, 2};
int[] sort = sort(one);
System.out.println(Arrays.toString(sort));
}
public static int[] sort(int[] array) {
// 临时变量,用于交换值
int temp = 0;
// 外层循环,判断我们要走多少次,应该走数组元素个数-1次,防止溢出
for (int i = 0; i < array.length-1; i++) {
// 通过flag标识位减少没有意义的比较
boolean flag = false;
// 内层循环,循环次数每交换i次减少i次
for (int j = 0; j < array.length-1-i; j++) {
// 比较两个数大小,与交换位置
if (array[j+1] < array[j]){
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
flag = true;
}
}if (flag == false){
break;
}
}
return array;
}
}
public class Mani {
public static void main(String[] args) {
// 1.创建一个二维数组 11*11 0:表示没有棋子,1:表示黑棋,2:表示白棋
int[][] array1 = new int[11][11];
array1[1][2] = 1;
array1[2][3] = 2;
// 输出原始数组
for (int[] a:array1) {
for (int b:a) {
System.out.print(b+"\t");
}
System.out.println();
}
// 2.转换为稀疏数组保存
// 第一步:获取有效值个数
int sum = 0;
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if (array1[i][j] != 0){
sum++;
}
}
}
System.out.println("有效值个数 = " + sum);
// 第二步:创建一个稀疏数组
int[][] array2 = new int[sum+1][3];
// 定义表头
array2[0][0] = 11;
array2[0][1] = 11;
array2[0][2] = sum;
// 第三步:遍历二维数组,将非零的值,存放到稀疏数组中
// 定义一个变量跳过表头
int count = 0;
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1[i].length; j++) {
if (array1[i][j] != 0){
count++;
array2[count][0] = i;
array2[count][1] = j;
array2[count][2] = array1[i][j];
}
}
}
// 第四步:输出稀疏数组
for (int i = 0; i < array2.length; i++) {
System.out.println(array2[i][0]+"\t"+array2[i][1]+"\t"+array2[i][2]);
}
// 3.如何将稀疏数组还原
// 第一步:读取稀疏数组
int [][] array3 = new int[array2[0][0]][array2[0][1]];
// 第二步:还原值,注意不要读取表头,i要等于1
for (int i = 1; i < array2.length; i++) {
array3[array2[i][0]][array2[i][1]] = array2[i][2];
}
// 第三步:输出
for (int[] g:array3) {
for (int f:g) {
System.out.print(f+"\t");
}
System.out.println();
}
}
}
六.Java规范约束
阿里巴巴开发手册 :
《阿里巴巴Java开发手册(终极版)》-藏经阁-阿里云开发者社区 (aliyun.com)
idea的设置