因为在听java课的时候对语法非常不熟悉,虽然也能看懂,但为了方便后续的学习,最近抽了点时间把java这边的语法课了一下,把一些和c有区别的地方标记了一些,基本上是想到哪写到哪,比较乱,仅作为自己学习的参考资料。
因为平时会补充,所以很多可能会重复,给的代码每次也不一样
数据类型
byte , short , Int , long , float , double
char , String
boolean(c中的bool)
区别与c,java中中文字符char只占一个字节,c中占两个字节
char的‘+’操作
1.
2.int k=(int)+(double)不合法,(int)+(double)=(double)
循环-判断-选择
这块和c基本一致
就循环那边多了个for-each,和c++的迭代器auto很像
然后switch那边,case后面可以接字符串,这点和c也不一样
数组:
定义方式:
数据类型[ ] 数组名称=new 数据类型[元素个数](new的作用是为数组申请内存空间)
区别于c,这里的元素个数可以是变量,可以先输入元素个数,再在此基础上进行数组的定义
数组元素的存储
java区别于c
java中数组名存储在栈内存,数组的元素连续存储在堆内存,数组一旦初始化完成,在栈内存分配的空间就定下来,存在栈内存的数组名存储了数组元素在堆内存的地址,通过数组名加上下标就能找到数组各元素在堆内存的位置
所以swap(a[i],a[j])是可以实现的,因为交换操作是直接在数组存储的堆内存中进行的
数组是引用类型,而int这类定义是传值类型,所以交换swap(int a,int b)实现的只是传入的副本的交换,对实际的参数不起作用,实际参数和形式参数在栈内存中是分开存储的。
内存分配
关于new的使用:
1、数组的定义上的不同:
以一维数组的定义为例来说明:
C语言中的定义格式为:type arrayName[常量表达式]; 其中类型type可以为 C中任意的数据类型,数组名 arrayName为一个合法的标识符,常量表达式指明数组的大小,在C语言中数组的大小不允许作动态的定义。
例如:int a[5];
声明一个整型数组a,长度为5,包含a[0]、a[1]、a[2]、a[3]、a[4]这5个整型元素,在内存中为这个数组分配一片连续的内存空间存放这5个元素,数组名可以表示数组的首地址,但并没开创一个内存空间来存放数组名。
它在内存中的表现形式为:a[0]a[1]a[2]a[3]a[4]
Java中的定义格式为:type arrayName[]或 type[] arrayName;
其中类型type可以为 Java中任意的数据类 ,数组名 arrayName为一个合法的标识符,[]指明该变量是一个数组类型变量。
例如:int a[];
声明一个整型数组,数组名表示一个引用地址变量,与C不同,Java在数组的定义中并不为数组元素分配内存,因此[]中不用指出数组中元素个数,,即数组长度,而且对于如上定义的一个数组是不能访问它的任何元素的。
我们必须用new运算符为它分配内存空间,其格式如下:arrayName = new type[arraySize];
其中arraySize指明数组的长度。 如 :
a = new int[5];
为一个整型数组分配5个 int型整数所占据的内存空间 ,这两部分可以合在一起,格式如下:
type arrayName = new type [arraySize];
例 如 :
int a= new int[5];
它在内存中的表现形式为:
a
a[0]a[1]a[2]a[3]a[4]
由上图可以看出,数组名有一个单独的内存空间,存放数组对象的引用地址。这与C语言是不同的。
原文| https://download.csdn.net/download/looseleafs/2202910?
上面这段引用总结一下
就是c中数组声明好数组名,定义好长度length,系统自动分配length长度的一片连续的内存空间给数组,数组名就是首地址,所以不用开创一个内存存放数组名;而java是按照给定的内存大小分配内存空间,接着让数组名指向分配的内存空间,数组名的作用相当于指针。(数组名表示一个引用地址变量,所以[]中无需指明数组个数,也不能访问他的任何元素。得先为他的分配内存空间才能访问, int a[] = new int[5];)
共同指向一片内存空间
内存分配过程:
public static void main(String[] args) {
//psvm
int a[];
int arr[]={
1,2,3,4};
a=arr;
System.out.println(a);//[I@4554617c
System.out.println(arr);//[I@4554617c
int b[]={
1,2,3,4};
System.out.println(b);//[I@74a14482
for(int i=0;i<a.length;i++)
System.out.println(a[i]);
//1
//2
//3
//4
System.out.println(a==b);//false
System.out.println(a==arr);//true
}
(提醒,后面和刚补充的关于内存的有些重复了)
使用:
int[] array=new int[10]
Int[] array={1,2,4}//下面的简易版
Int[] array=new int[]{1,2,3}//静态初始化
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int[] a={
1,2,3,4};
int[] b=new int[a.length];
for(int i=0;i<a.length;i++)
b[i]=a[i];
System.out.print(a==b);//false(==对于引用型变量是判断地址值是否相同)
int[] c=a;
System.out.print(a==c);//true
}
这里的array,arrayB共用一块空间,所以对arrayB做改变也改变了array
Int[] a=new int[10],a里面并没有数组,而是作为一块空间/一个数组的管理者,a指向这片空间
这也是数组变量和普通变量的区别,数组变量的数组名是管理者,而普通变量的变量名是所有者
Int[] b=a,就表示a和b共同管理a所管的那片空间
在c中就不能直接定义一个新的数组变量指向已有数组,只能通过for或者赋值函数将已有数组内的元素一个个复制到新的数组内部,java中数组也能复制,采取遍历的方法
Java中将管理者指派同样一块空间,对管理者进行比较结果是true
但如果是另外分配新的空间
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int[] a = new int[]{
1, 2, 3, 4};
int[] b = new int[]{
1, 2, 3, 4};
System.out.print(a == b);//false
}
}
即指数组内部元素全部一样,两个管理者进行比较也是false,因为地址不同
扩展总结
==用于基本数据类型比较的时候比较的是数值,如果比较的是引用数据类型遍历,则是比较两对象的地址值是否相同
equals只适用于应用数据类型
object类中定义的equals()和==的作用是相同的,比较两个对象的地址值是否相同,即两个引用是否指向同一个对象实体。
像String、Date、File、包装类等都重写了equals()方法,重写以后,比较的不是两个引用指向的地址是否相同,而是两个对象的实体内容是否相同。
字符串:
int.next()和in.nextLine()的区别就像gets和getline
String str=in.next();
System.out.println(str);
// Hello world
// Hello
String str2=in.nextLine();
System.out.println(str2);
// Hello world
// Hello worl
扩展:next()和nextLine()的区别详解
next()方法在读取内容时,会过滤掉有效字符前面的无效字符,对输入有效字符之前遇到的空格键、Tab键或Enter键等结束符,next()方法会自动将其过滤掉;只有在读取到有效字符之后,next()方法才将其后的空格键、Tab键或Enter键等视为结束符;所以next()方法不能得到带空格的字符串。
nextLine()方法字面上有扫描一整行的意思,它的结束符只能是Enter键,即nextLine()方法返回的是Enter键之前没有被读取的所有字符,它是可以得到带空格的字符串的。
————————————————
原文链接:https://blog.csdn.net/qq_38986609/article/details/78598103
=与==
对于基础类型
比如int a,b; a=b,只是赋值,
而对于字符串和数组,
String a,b,a=b表示的是a,b是共同管理一块空间的
a==b判断的是所用的内存空间是否一致,而不是内容是否一致
判断内容是否一致用a.equals(b),相等输出true
总结:对于字符串来说,“==”判断是否是同一个东西,equals判断是否是相同的内容
两个字符串比较大小用compareTo
s1.compareTo(s2)
compareToIgnoreCase 可以不区分大小写比较大小
字符串的一些方法
- length()函数可以得到字符串的长度,注意区分,字符串这个有括号,数组的无括号
- 如果想要访问 一个字符串的单个字符,用函数charAt(index),第一个字符的index是0
Index的范围是0~length()-1
字符串的遍历不能用for-each,字符串也不在能像c那样当成一个字符数组将字符一个个拆出来遍历,要想遍历字符串的元素只能charAt
本来想弄个字符数组的,结果发现没有nextChar…
String str= in.nextLine();
for(int i=0;i<str.length();i++){
char c=str.charAt(i);
}
- 得到子串: s.substring(int n)得到n位到末尾的全部内容
s.substring(int b,int e)得到b到e之前的内容. - (只能找到第一次出现的位置)
从左边开始找:
s.indexOf(char c),找字符串中c的位置,如果没有返回-1
s.indexOf(char c,int n),从n号位置开始找c
s.indexOf(string str),找到子串str所在的位置
从右边开始找:
s.lastIndexOf(char c), s.lastIndexOf(char c,int n),
s.lastIndexOf(string str),
扩展:
- s.startWith(string str),
s.endWith(string str),
看s是不是以str开头或者结尾的,boolean - s.trim(),删掉s开头和结尾的空格
- s.replace(c1,c2),把所有c1换成c2
- s.toLowerCase()
- s.toUpperCase()
全部换成大写字母小写字母
boolean contains(str); 字符串中是否包含某一个子串。
indexOf比起contains的特殊之处:indexOf(str):可以索引str第一次出现的位置,如果返回-1表示该str不在字符串中存在,所以,也可以用于对指定判断是否包含。if(str.indexOf(“aa”)!=-1)
而且该方法既可以判断,又可以获取出现的位置
- boolean isEmpty():
- 字符中是否有内容,原理就是判断长度是否为0
但是这些有修改功能的操作都不能改变原字符串本身,它的作用只能在新创造的字符串上显示
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
String s1="abcd";
s1.replace('a','d');
System.out.println(s1);//abcd
String s2=s1.replace('a','d');
System.out.print(s2);//dbcd
}
字符串的连接
public class temp {
public static void main(String args[]){
System.out.println("Hello"+" "+"World");
//或者
String str1="Hello ",str2="World";
String str=str1+str2;
System.out.println(str);
//Hello World
}
}
String str1="Hello ",str2="World";
str1=str1+str2;
System.out.println(str1);
//Hello World
但为什么说字符串是不可变更的
正是因为字符串不可变更,所以像这样的字符串拼接代码尽量不要出现
但是我们知道我们的JVM功能是特别强大的,实际上只要我们出现此类字符串拼接的操作,实际编译运行的时候都不是像图上的那样,因为那样产生了太多的垃圾空间,效率很低。
所以字符串操作,字符串拼接实际上用到的并不是String类的操作,而是StringBuffer和StringBuilder
原文链接:https://blog.csdn.net/qq_42006733/article/details/98336609
出现字符串以后+作为连接运算符,否则就是算术运算符
字符串在java中对于单个字符是不可修改的,只能制造新的字符串,所以如果要进行字符串的修改只能先拷贝修改再赋给新的字符串
方法(c中称为函数)
在数组中length不带(),字符串的带,字符串的length()就是一种方法(函数)
在定义方法时如果需要传参数,当期望参数等级高于实际参数,编译器会自动将参数强制转换
方法传的只是一个参数,在方法里面对变量参数进行改变,不会改变变量原本的值,java和c不一样,java没有指针,java语言在调用函数,永远只能传值给函数(以后有发现再更改
方法重载
但是java和c有一个非常大的区别就是java存在方法重载而c连基本的方法重载都实现不了。
什么是方法重载,简单的说就是在同一个类中存在多个方法共用一个名称,但是传入的参数类型,参数个数可能会不同,在调用方法的时候,系统会根据参数的不同选择对应的方法。
方法重载在调用的时候只能通过参数进行方法调用的判断
public class Main {
public static void helloWorld(int a){
System.out.println("hello");
}
public static void helloWorld(int a,int b){
System.out.println("world");
}
public static void main(String[] args) {
//psvm
helloWorld(1);//hello
helloWorld(1,1);//world
}
}
关于Java中new的使用
简单说明一下new对象和=对象的区别
先说一下 :
String a = 'test';// 1
String b = new String("test"); 2
的区别吧
1这种方式JVM会先去共享的字符串池中查找,有没有"test"这个词,如果有直接返回它的引用;如果没有,就会创建这个对象,再返回,因此,“a”+“b"相当于存在3个对象,分别是"a”、“b”、“ab”。
而new String(“test”),则省去了查找的过程,直接就创建一个b的对象,并且返回引用
这一块
原文链接:https://blog.csdn.net/jiangwudidebaba/article/details/89372728
集合-ArrayList
(很像STL的set,基本一样)
其实想放在数组那边记录,但还是另外开一个目录吧。
ArrayList<类型>
ArrayList是集合,不同于数组确定了空间大小就不能更改空间大小了,ArrayList可以动态分配内存空间,动态添加数据元素。
也可以说ArrayList就是动态数组。
ArrayList的构造和添加
注意!指定位置添加不能超过当前集合的结尾,可以在结尾添加元素,相当于add(e),不能超过结尾。
public static void main(String[] args) {
//构造ArrayList
ArrayList<String> array=new ArrayList<>();
System.out.println(array);//输出:[]
//添加(是从尾部进行添加的)
array.add("hello");
array.add("world");
System.out.println(array);//输出:[hello, world]
array.add(1,"ok");
System.out.println(array);//[hello, ok, world]
array.add(3,"happy");
System.out.println(array);//[hello, ok, world, happy]
//IndexOutOfBoundsException:
// array.add(6,"error");
// System.out.println(array);
}
ArrayList的常用方法
jdk自带包
random
sort
https://blog.csdn.net/jackleeonlyone/article/details/110853258
https://www.cnblogs.com/macyzhang/p/9861302.html
关于文件??
为什么写入最后需要out.close()