java语法
在介绍java中,我会去书写一些java语言与C++的不同点。
目录
变量、运算符、输入与输出
内置数据类型
类型 | 字节数 | 数据范围 |
byte | 1 | -128~127 |
short | 2 | -32768~32767 |
int | 4 | -2147483648~2147483647(2*10^9) |
long | 8 | -9223372036854774808~9223372036854774807(9*10^18)例如:1324323L(表示常数L) |
float | 4 | 精度6~7位 例如:1.2F,与c++相同 |
double | 8 | 精度15~17位 例如:1.2,1.2D(1.2默认类型为Double) |
boolean | 1 | true、false |
char | 2 | 'A' 根据ASCLL存储 |
除了基本数据类型之外,Java提供了Integer对int的封装类,Java还提供了BigDecimal
类来处理高精度小数。BigDecimal
类可以表示任意精度的小数,其小数位数不受限制,可以满足各种计算需求。
注意:与C++不同的
1、java中的long类型相当于c++中的long long类型
2、java中有2个字节,而c++中的char只有1字节
3、java中int类型没有boolean的属性,c++中数字0表示false,其他表示true等
常量
使用final修饰常量,相当与c++中的const
运算符
显示转化:与c++相同,int d=(int)3.1415;
隐式转换:与c++不同,只能从高精度转为低精度。
注意:int a=3.14*5,在java中会报错,在c++中会得到15的结果
表达式:与c++基本相同。如:int a=b*c+d;
注意:java中不能使用a=b,c=d....;会报错。
正确写法
a=b;
c=d;
.....
当然,在申明变量时,如:int a=1,b=2,c=10;这样是支持的。
两种输入输出
输入
方法一
//这种是快速输入,输入时的效率不高,相当于c++中cin
import java.util.Scanner;
Scanner sc=new Scanner(System.in);
//输入字符串
sc.next()
sc.nextLine()//最为特殊,会接受无效字符,其他输入形式都不会。
//输入数字类型---与sc.next()的接受方式相同,只接受有效字符,不接受无效字符(enter、blank、tab)
sc.nextByte();
sc.nextShort();
sc.nextInt();
sc.nextLong();
sc.nextBigInteger();
//输入浮点类型
sc.nextFloat();
sc.nextDouble();
//输入boolean类型
sc.nextBoolean();
注意:next()和nextLine()的区别
1、next()只接受有效字符串,当有效字符前有无效字符(tab、blank、enter)会直到接收到有效字符,之后遇到无效字符会结束。如:输入“ hello world",输出:“hello”
2、nextLine()接受一行字符串,当遇到enter时,会结束。
//next()不会接受enter等无效字符 String str1=sc.next(); String str2=sc.nextLine(); 输入 chenzihao hello world 输出 chenzihao null
方法二
import java.io.BufferedReader;
import java.io.InputStreamReader;
//较为高效的输入方法,相当于c++中scanf
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
//读入一行,与sc.nextLine()有相同的性质,会接受无效字符
br.readLine();
//读入一个字符,返回它的ASCLL值
br.read();
//读入数字的方法
//一个数字
String a=br.readLine();
Integer c=Integer.parseInt(a);
//多个数字,使用blank隔开
//Double.parseInt()、Float.paraseFloat()
//其他类型转换为字符串:Integer.toString()、Double.toString();
String[] str=br.readLine().split(" ");
for(String a:str){
System.out.println(Integer.parseInt(a));
}
br.close();
输出
方法一
//普通的输出
//前两种区别便是是否输出后换行
System.out.println();
System.out.print();
//相当于c++中printf,区别便是在输出浮点数时,java只有%f。无论float还是double
System.out.printf();
//样例
System.out.printf("%04d %.2f",x,avg);
方法二
import java.io.BufferedWriter
import java.io.OutputStreamWriter;
//对System.out.println()的优化
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));
//输出字符串
bw.write(str);
//追加字符串
bw.append(str);
//输出字符格式
bw.write(str,off,len);
//输出数字类型
Integer t=1314;
bw.write(t.toString());
//换行
bw.newLine();
//刷新缓冲池
bw.flush();
//关闭输出流
bw.close();
判断语句
if-else语句
//与c++唯一的区别,便是int中的0或者1不能当作条件判断
//错误演示
int a=1;
if(a) System.out.println(a); ❌
//正确演示
int a=1;
if(a!=0) System.out.println(a); √
switch语句
//与c++中相同
package com.acwing;
import java.util.Scanner;
public class Demo02{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
Integer day=sc.nextInt();
String ans="";
switch(day){
case 1:
ans="Monday";
break;
case 2:
ans="Tuesday";
break;
case 3:
ans="Wednesday";
break;
case 4:
ans="Thursday";
break;
case 5:
ans="Friday";
break;
case 6:
ans="Saturday";
break;
case 7:
ans="Sunday";
break;
default:
ans="输入错误,请输入1~7的数字";
break;
}
System.out.println(ans);
}
}
逻辑表达式和条件运算符
作者累了,要休息几天在更新。。。。敬请期待。
循环语句
数组
-
数组可以进行赋值,它们存储的是同一段地址,如char[] c={'a','b','c'};char[] b=c;其中b中元素改变,c中的元素也会改变
-
字符数组要注意:如char[] c="abc";❌在c++中可以但在java中是不可以的
-
等于号”==“只可以用在基本类型中,对象就要使用equals或者hashCode
-
一维数组可以使用Arrays.toString(arr)转换为字符串输出,二维数组可以使用Arrays.deepToString(arr)转换为字符串输出
-
基本类型查看是地址使用num.hashCode();
-
数组中的API
-
Arrays.sort():只适用于一维数组,sort(num,(a,b)->a-b);
-
Arrays.fill():只适用于一维数组
-
Arrays.toString():只是用与一维数组
-
Arrays.deepToString():二维数组使用
-
字符串
-
字符串是常量,不能被修改。使用charAt(index)去索引对应的字符
-
“+”可以进行字符串拼接,如st+=10;——隐式转换
-
st=tmp——进行地址的赋值,所以在字符串中“==”比较的是两个字符串的地址,要使用equals进行比较
-
String.format("%04d %.2f",10,1.2);类似于c++中的sprintf(),返回一个字符串
-
String temp=3.1415926; double db=Double.parseDouble(temp);字符串转换为Double类型
-
常用API
-
length()——返回字符串长度
-
indexOf(char) ,indexOf(String)查找字符或者字符串的索引,返回查到的第一个字符的索引,没有找到返回-1
-
split(parameteres),按照parameteres字符进行分割字符串,返回字符串数组
-
equals()——相等返回true,反之则返回false
-
st1.compareTo(st2)——比较两个字符串,按字典顺序进行比较。返回负数——小于,0——相等,正数——大于
-
instanceof——保留关键字,作用是判断左边是否是右边的类型,返回boolean类型
-
startsWith(String,int)——判断字符串是否以某字符串开头,第二个参数表示从原字符串开始查找的位置
-
endsWith(String)——判断字符串是否以某字符串结尾,没有 第二个参数
-
trim()——去掉前后空白字符,返回一个新字符串
-
toUpperCase()——全部转换为大写字符,返回一个新字符串
-
toLowerCase()——全部转换为小写字符,返回一个新字符串
-
replace(oldValue,newValue)——替换字符或者字符串,返回新字符串
-
substring(beginIndex,endIndex)——截取字符串,返回新的字符子串——[beginIndex,endIndex)
-
-
可变字符串:StringBuffer——线程安全,速度慢,StringBuilder——线程不安全,但速度快
-
setCharAt(index):修改字符,无返回值
-
append(String|char):添加字符,返回StringBuffer|StringBuilder,原字符串也会被修改
-
charAt(index):与String中基本相同
-
reverse():翻转字符,放回StringBuffer|StringBuilde,原字符串也会被修改
-
函数
-
static相当于c++中的全局变量,所用实例共用一个属性或函数
-
如果是static函数只可以调用static变量或者函数
类与接口
-
一个java源文件中只能有一个public类,但可以有多个类
-
extends可以使子类继承父类的一些属性和方法
-
父类使用了有参构造,子类也需要有参构造,且在第一行插入super()函数调用父类有参构造
-
不可以继承private属性和方法,构造方法也不能被继承,只能通过super()进行调用,supper.getX()|getX();
-
接口可以继承多个接口,但类只能继承一个父类
-
-
同一目录下,不用import引入
集合
-
List接口
-
有两个实现类——ArrayList和LinkedList
-
常用API
-
list.add(elem)——增加,成功返回true
-
list.set(index,elem)——修改,返回旧值
-
list.get(index)——查询,返回下表对应的值
-
list.remove(index|Object)——删除,成功返回true
-
list.clear()——清除集合中所用元素
-
list.contains(elem)——判断是否存在该元素,存在返回true
-
list.isEmpty()——判断是否为空
-
list.size()——返回集合中元素的数量
-
list.iterator()——返回迭代器
-
-
四种遍历方式——适用于许多集合(List,Stack)
//遍历的四种方式 //普通遍历 //方式一 for(int i=0;i<list.size();i++){ System.out.println(list.get(i)); } System.out.println("*********************"); //方式二 for(String item:list){ System.out.println(item); } System.out.println("*******************"); //方式三:迭代器 Iterator<String> temp = list.iterator(); while(temp.hasNext()){ System.out.println(temp.next()); } System.out.println("*********************"); //方式四:forEach——优化版 list.forEach((item)->{ System.out.println(item); });
-
-
Stack集合——这不是接口,而是类,可以直接创建对象
-
该集合继承了vetor集合
-
常用API
-
继承了vector集合的API
-
stk.add(elem)——增加,成功返回true
-
stk.set(index,elem)——修改,返回旧值
-
stk.get(index)——查询,根据下标查询
-
stk.remove(index|elem)——删除,返回删除元素
-
stk.isEmpty()——判断是否为空
-
stk.clear()——清空栈中元素
-
stk.size()——判断栈中有多少元素
-
stk.contains(elem)——判断是否存在elem元素
-
stk.iterator()——返回迭代器
-
-
它自己的API
-
stk.push(elem)——增加,返回插入的元素
-
stk.search(elem)——查找,根据元素从栈顶元素开始查找
-
stk.pop()——弹出栈顶元素,返回栈顶元素
-
stk.peek()——返回栈顶元素
-
stk.empty()——判断是否为空
-
-
-
对栈进行遍历——遵循先进后出的原则
while(!stk.empty()){ System.out.print(stk.pop()+", "); }
-
-
Queue接口
-
其有两个实现类,LinkedList和PriorityQueue
-
实现大根堆的方法——new PriorityQueue<>(Collections.reverseOrder())
-
常用API
-
增加:q.add(elem)、q.offer(elem)——成功,返回true,失败offer()返回false
-
弹出队头:q.remove()、q.poll()——成功,返回被删除元素elem,poll()失败返回null
-
查询队头:q.element()、q.peek()——成功,返回该元素,peek()失败返回null
-
q.size()、q.isEmpty()、q.contains(elem)、q.clear()
-
-
遍历
while(!q.isEmpty()){ System.out.println(q.poll()); }
-
-
Set接口
-
其有两个实现类,HashSet和TreeSet,TreeSet是有序序列,而HashSet是无序的
-
与List接口最大的区别在于,Set接口会自动查重
-
常用API
-
增加:s.add(elem)——成功,返回true
-
删除:s.remove(elem)——成功,返回true
-
s.size()、s.isEmpty()、q.contains(elem)、q.clear()
-
ceiling(elem)、floor(elem)——TreeSet独有的,返回大于等于elem的最小值,小于等于elem的最大值,失败返回null
注意:ceiling(elem)其中elem可以是任何数,不一定是TreeSet集合中的数
-
-
遍历
Iterator<Integer> it=s.iterator(); while(it.hasNext()){ System.out.println(it.next()); }
-
-
Map接口
-
其有两个实现类——HashMap和TreeMap
-
TreeMap可以更加key值进行排序
-
常用API
-
增加:map.put(key,value)——成功,返回添加的元素的value值
-
修改:map.put(key,value)——注意,key值是map结合中已经有的元素
-
查询:map.get(key)——根据key值进行查询
-
删除:map.remove(key,[value])——成功,返回true
-
其他
-
map.keySet()——返回所有key值的Set集合
-
map.values()——返回所有value值的Collection集合
-
map.entrySet——返回Set<Map.Entry<E,E>>集合
-
map.size()、map.containsKey(key)、map.containsValue(value)、map.isEmpty()
注意:Map.Entry相当于c++中的pair TreeMap独有 ceilingEntry(key)、floorEntry(key)——返回Map.Entry<E,E> ceilingKey(key)、floorKey(key)——返回key值
-
-
-
遍历
//遍历 Set<Integer> items = map.keySet(); for(Integer item:items){ System.out.printf("key=%d,value=%s\n",item,map.get(item)); } //Entry的基本用法 Set<Map.Entry<Integer,String>> mapItems=map.entrySet(); for(Map.Entry<Integer,String> item:mapItems){ //修改Value值,并且返回旧值 System.out.printf("oldValue:%s\n",item.setValue("woshi"+item.getValue())); //两个方法——getKey()、getValue() System.out.printf("key:%d,value:%s\n",item.getKey(),item.getValue()); } //只要它的值 Collection<String> values = map.values(); values.forEach((item)->{ System.out.println(item); });
-
-
泛型
类似于C++的template,Java的类和接口也可以定义泛型,即同一套函数可以作用于不同的对象类型。泛型只能使用对象类型,不能使用基本变量类型。