1.初识JAVA----JAVA文件是怎么进行编译的
面试题:String[] args这个参数是干什么的?
args是运行时的命令行参数,在java HelloWorld后面加上一些参数,就会放在args的数组当中;
1.通过写文件的方式来写java程序
把文件扩展名打开,后缀名写成.java,就变成了.java文件,javac就是java的编译器;想要编译,输入javac HelloWorld.java,再输入输入java HelloWorld,即编译成功;
java HelloWorld My name is lijiawei,那么这时,args数组里面的内容就是My name is lijiawei,args[0]=My,args[1]=name,args[2]=is......
2.java的编译过程
.java程序,在源代码上,目前在磁盘上就是一大堆的代码,我们写的代码,目前只有我们自己认识,但是我们想要让编译器认识;不需要把这个文件进行编译,把他转化成计算机,编译器能够认识的东西,从而可以执行;编译以后会变成.class文件;
JVM:叫做java虚拟机,java程序就是跑在JVM里面,把对应的字节码文件拉取过来,然后进行执行
.java文件->会经过编译,javac命令,文件名是.java->.class文件(叫做字节码文件,二进制文件,包含了类中的信息)------>JVM(一个软件,C/C++写的)
javac HelloWorld.java先把.java文件编译成字节码文件,在命令行里面再进行输入java HelloWorld按一下回车就可以运行程序了
JDK里面包含着JRE,JRE里面包含着JVM;
注意:是一个类对应一个字节码文件,在执行到某个类的时候,用到哪个类,就加载某个类;
3.java中的数据类型
变量:相当于是一个箱子,有类型也有大小
final int a=10;a是常量,有final修饰的变量,叫做常量
重载:同一个方法名字,提供不同版本的实现,成为方法重载;但是当两个方法名字相同的时候,参数列表相同,返回值不同,不会构成重载;
1)方法名相同
2)方法的参数列表不同(参数个数或者是参数类型)
3)方法的返回值不做要求
public static int add(int a,int b)
{
return a+b;
}
public static int add(int a,int b,int c)
{
return a+b+c;
}
public static void add(int a,int b,int c,int d)
{
System.out.println(a+b+c+d);
}
public static void main(String[] args) {
System.out.println(add(1,2));
System.out.println(add(1,2,3));
add(1,2,3,4);
}
常量指的是运行时类型是不可以发生改变的,变量指的是运行时可以发生改变的量
1)在java中,一个int变量占4个字节,所表示的范围在-2^31-2^31-1
我们要想查找int的最大值,最小值
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
2)long
long 变量名=初始值; long num=10L;
在java中,long类型占有8个字节,表示的数据范围在-2^63-2^63-1
System.out.println(Long.MAX_VALUE);
System.out.println(Long.MIN_VALUE);
3)双精度浮点型变量
double 占8个字节
float 占4个字节
在java中,int/int的值仍然是int,如果想要得到0.5,就需要使用double来进行计算
4)char占2个字节,计算机中的字符本质上是一个整数,我们经常使用ASCLL来表示字符,在java中我们经常使用Unicode来表示字符,所表示的字符种类要更多;表示的范围是0-65535
5)short变量,占用两个字节-2^15-2^15-1
6)byte变量,占用一个字节-128-127
7)boolean,true和false两种取值
4.java中的类型转换
1)不同数字类型的变量相互赋值,表示范围小的类型可以转化成范围较大的类型,反之则不行;
int a=10;
long b=a;//long表示范围更大,可以将int复制给long
long c=90;
int b=c;//此时编译会不通过,因为提示可能会丢失精度
2)互不相关的两种类型,是不可以进行相互赋值的
int a=10;
boolean b=a;
这里会提示编译出错,提示不兼容的类型
3)使用字面值常量赋值的时候,java会自动进行一些检查校验,判断复制是否合理,byte a=127,编译通过;byte b=128,编译就会出错,已经超出范围,会提示从int转换到byte可能会有损失
5.整型提升
1)不同的数据进行混合运算,范围小的会自动转换成范围大的类型
int a=10;
long b=20;
int c=a+b;//编译出错
long d=a+b;//编译成功
int e=(int)(a+b);//编译成功
原因:当int和long进行混合运算,int会自动提升成long,所以得到的结果也是long类型,所以我们要用long类型的变量来接受结果(用int就会报错,因为大的类型不能赋值给小的类型,除非进行强制类型转换)
2)对于short和byte这种比4个字节小的类型,会优先转化成4个字节的int,再进行相加
byte a=10;
byte b=20;
byte c=a+b;//编译报错
byte d=(byte)(a+b);//编译成功
a b 都是byte类型,但是在进行a+b的运算的时候,会先提升类型为int,然后再进行相加运算,这是运算出的整体结果就是int,赋值给d时,byte类型就会出现报错;
6.int与String之间的相互转换
//1 int转换成String
int a=10;
String str1=a+"";
System.out.println(str1);
String str2=String.valueOf(a);
System.out.println(str2);
//2 String 转换成int
String str="100";
int num=Integer.parseInt(str);
System.out.println(num);
7.一些算数运算符的常见问题
//1 a++和++a的区别
int a=10;
int b=a++;//先进行赋值,在进行++
int c=++a;//先进行++,在进行赋值
System.out.println(b);//10
System.out.println(c);//12
//2 注意关系运算符的返回值都是boolean类型
//3 位运算符
位运算表示按二进制位来进行运算,计算机中都是使用二进制位来进行表示数据的(0,1构成的序列),位运算就是再按照二进制位来进行每一位的运算;
1)按位与&
如果两个二进制位都是1则是1,否则结果为0
2)按位或|
如果两个二进制位都是0则位0,否则结果是1
3)按位取反~
是0改成1,是1改成0
4)按位异或^
如果两个数字的二进制位相同,那么结果就是0,不相同结果就是1
//4移位运算
1)<<左移
最左侧不要了,右侧补0
2)>>右移
最右侧不要了,左侧补0
//3条件运算符
表达式1?表达式2:表达式3,当表达式1的值是true的时候,整个表达式的值是表达式2;当表达式1的值是false的时候,整个表达式的值是表达式3;
是闰年的条件:被4整除,但是不可以被100整除;或者可以被400整除
year%4==0&&year%100!=0||year%400==0
//4 switch括号中不可以写的类型
“java中switch()括号中不能放“long”,“float”,“double”,“boolean”类型的数据,可以使用“byte”,“short”,“char”,“int”,“枚举类型”,“String”类型的数据。”
练习题1:求斐波那契数列的第n项,1,1,2,3,5,8 ,13,21,34;
public static int fib1(int n)
{
if(n==1||n==2)
{
return 1;
}else{
return fib1(n-1)+fib1(n-2);
}
}
public static int fib2(int n)
{
int f1=1;
int f2=1;
int f3=1;
while(n>2)
{
f3=f1+f2;
f1=f2;
f2=f3;
n--;
}
return f3;
}
练习题2:青蛙跳台阶问题:1,2,3,5,8..........
练习题3:汉诺塔问题
public static void move(char pos1,char pos3)
{
System.out.println(pos1+"->"+pos3);
}
public static void hannuo(int n,char pos1,char pos2,char pos3)
{
if(n==1)
{
move(pos1,pos3);
return;
}else{
hannuo(n-1,pos1,pos3,pos2);
move(pos1,pos3);
hannuo(n-1,pos2,pos1,pos3);
}
}
_________________________________________________________
2.一维数组
1)创建数组
int[] arr1={1,2,3,4,5,6};
int[] array=new int[4];
int[] array1=new int[]{1,2,3,4,5,6};
2)遍历数组,for循环可以拿到数组的下标,但是for,each不行;
//1.for循环进行打印
for(int i=0;i<arr1.length;i++)
{
System.out.println(arr1[i]);
}
//2.通过foreach的方式来进行打印
for(int s:arr1)
{
System.out.println(s);
}
//3直接调用静态方法
System.out.println(Arrays.toString(arr1));
}
3)自己实现一个数组转化成字符串的例子
public static String toString(int [] arr1)
{
String ret="[";
for(int i=0;i<arr1.length;i++)
{
ret+=arr1[i];
if(i!=arr1.length-1)
{
ret+=", ";
}
}
ret+="]";
return ret;
}
public static void main(String[] args) {
int[] arr1 = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9};
System.out.println(toString(arr1));
}
数组转化成字符串
Arrays.toString(arr1)
int arr1[]=new int[]{1,2,3,4,5};
String str1=Arrays.toString(arr1);
System.out.println(str1);
4)数组的拷贝
1)返回值是一个新的数组=Arrays.CopyOf(一开始要拷贝的数组,要拷贝的数组的长度)
int arr1={1,2,3,4,5,6,7,8,9};
int[] ret=Arrays.CopyOf(arr1,arr1.length());
System.out.println(Arrays.toString(ret));
2)System.ArrayCopy(原数组,来时拷贝的原数组的位置,现在数组开始拷贝的位置,长度);
int array[]={1,2,3,4,5,6,7};
int ret=new int{array.length];
System.ArrayCopy(array,0,ret,0,array.length);
System.out.println(Arrays.toString(ret));
3)Object的克隆方法
int[] arr1={1,2,3,4,5,6,7};
int ret[]=arr1.clone();
4)数组的各个部分进行赋值
5) 数组中的其他常用方法
1)查找数组的元素
Array.binarySearch(原数组,开始查找的位置,最终查找到哪里,要查什么)
int arr1[]={1,2,3,4,5,6,7};
System.out.println(Arrays.binarySearch(arr1,2,5,4);
这个代码的语句是从二号位置到五号位置找4
2)拷贝数组的区间
int[] ret={1,2,3,4,5,6,7};
int[] arr1=Arrays.CopyOfRange(arr1,2,4);
3)判断两个数组是否相同
直接调用Arrays.equals(数组一,数组二);返回值是一个boolean类型
4)填充
int arr1[]=new int[10];
Arrays.fill(arr1,8);
是向arr1这个数组里面填充8里面的每一个元素都是8;
Arrays.fill(arr1,2,5,8);像这个数组的2到5位置填8;
5)检查一个数组是否有序
Arrays.sort(arr1);
6)数组转化成字符串
int arr1={1,2,3,4,5,6,7,8};
String html=Arrays.toString(arr1);
数组是在栈上,数组中的每一个元素在堆上
6)实现数组的二分查找和把所有的偶数都挪到奇数前面,并实现冒泡排序,以及数组的逆序
//1实现数组的二分查找
public static int binarysearch(int[] arr1,int key)
{
int left=0;
int right=arr1.length-1;
int mid=0;
while(left<=right)
{ mid=(right+left)/2;
if(arr1[mid]>key)
{
right=mid-1;
}else if(arr1[mid]<key)
{
left=mid+1;
}else{
return mid;
}
}
return -1;
}
//2实现数组的逆序
public static int[] resverse(int arr1[])
{
int left=0;
int right=arr1.length-1;
while(left<=right)
{
int temp=0;
temp=arr1[left];
arr1[left]=arr1[right];
arr1[right]=temp;
left++;
right--;
}
return arr1;
}
//3 实现所有偶数都移到奇数前面
public static void func(int[] arr1)
{
int left=0;
int right=arr1.length-1;
while(left<=right)
{
while (left<=right&&arr1[left]%2==0)
{
left++;//此时就可以保证left下标一定指向奇数
}
while(left<=right&&arr1[right]%2!=0)
{
right--;
}
int temp=arr1[left];
arr1[left]=arr1[right];
arr1[right]=temp;
}
}
//4 实现冒泡排序
public static void sort1(int[] arr1)
{
for(int i=0;i<arr1.length-1;i++)
{ boolean flag=false;
for(int j=0;j<arr1.length-1;j++)
{
if(arr1[j]>arr1[j+1])
{
int temp=arr1[j];
arr1[j]=arr1[j+1];
arr1[j+1]=temp;
flag=true;
}
}
if(flag==false)
{
return;
}
}
}
7)数组的循环右移,以及消失的数字,位运算习题
leetcode189题,旋转数组
public static void resverse(int [] arr1,int left,int right)
{
while(left<=right)
{
int temp=arr1[left];
arr1[left]=arr1[right];
arr1[right]=temp;
left++;
right--;
}
}
public static void reverseKey(int[] arr1,int n)
{ if(n>arr1.length-1)
{
n=n%arr1.length-1;
}
resverse(arr1,arr1.length-n,arr1.length-1);
resverse(arr1,0, arr1.length-1-n);
resverse(arr1,0, arr1.length-1);
}
public static void main(String[] args) {
int [] array={1,2,3,4,5,6,7,8,9};
reverseKey(array,3);
System.out.println(Arrays.toString(array));
}
leetcode
数组num中包含从0到n的所有整数,但是其中缺少了一个,找出缺失的整数,要求在O(N)时间内完成
思路:使用异或(相同为0,不相同为1)
2^3=1
00010
00011
相同的数异或之后就没了
让数组中的数依次和0-N的所有数进行异或,最后剩下的那个数字就是缺的那个数字
public static int func(int[] arr1)
{ int ret=0;
for(int i=0;i<arr1.length-1;i++)
{
ret=ret^arr1[i];
}
for(int j=0;j<arr1.length+1;j++)
{
ret=ret^j;
}
return ret;
}
8)判断一个数是否是素数
public static int isyear(int n)
{
for(int i=2;i<=Math.sqrt(n);i++)
{
if(n%i==0)
{
return 0;
}
}
return 1;
}
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int num=scanner.nextInt();
if(isyear(num)==1)
{
System.out.println(num+"是素数");
}else{
System.out.println(num+"不是素数");
}
}
9)判断一个数是否是水仙花数
水仙花数是指一个 3 位 数,它的每个位上的数字的 3次幂之和等于它本身。例如:1^3 + 5^3+ 3^3 = 153
public static boolean isNum(int n)
{
//1 首先判断它是几位数
int num=n;
int s1=0;
int sum=0;
int count=0;
while(num!=0)
{
num=num/10;
count++;
}
num=n;
while(num!=0)
{
s1=num%10;
num=num/10;
sum=(int)(sum+Math.pow(s1,count));
}
if(sum==n)
{
return true;
}else{
return false;
}
}
10)求两个数的最大公约数
第一种方法: int min=0;
if(num1>num2)
{
min=num2;
}else{
min=num1;
}
while(min>0)
{
if(num1%min==0&&num2%min==0)
{
return min;
}else{
min--;
}
}
return min;
3二维数组:他的本质上是一个一维数组,只不过二维数组中的每一个元素又是一维数组;
定义二维数组:分成规则的二维数组和不规则的二维数组
int array[][]={
{1,2,3},{4,5,6}};
int arr2[][]=new int[][]{
{1,2,3},{4,5,6}};//不需要写行数列数
int arr1[][]=new int[2][];//必须指定行
//1打印二维数组
for(int i=0;i<array.length;i++){
for(int j=0;j< array[i].length;j++){
System.out.print(array[i][j]+" ");
}
System.out.println();
}
//2以字符串的形式打印出来
System.out.println(Arrays.deepToString(array));
Arrays.toString(array);//这是打印出来的是两个地址
//3运用foreach进行循环打印
for(int[] temp:array)//这里面不可以用整形来接受
{
for(int x:temp)//因为二维数组中的每一个元素都是一维数组,我们先用temp数组来接受二维数组中的每一个元素,然后再进行循环打印
{
System.out.println(x);
}
}
在java中数组要指定行,列可以自己进行推导
int[][]array=new int[2][];
array[0]=new int[3]; {1,2,3}
array[1]=new int[2]; {4,5,6}
[]中写个数就不要写初始化,能够进行初始化就不要写个数