java的基本程序设计结构
1.数据类型
java是一种强类型语言。在java中,一共有8种基本类型——四种整型、两种浮点类型、一种字符类型和一种布尔类型。
(1)整型
- byte——1字节
- short——2字节
- int——4字节
- long—— 8字节
注:java没有任何无符号形式(unsigned)的整型类型 ,但是有将有符号整数值解释为无符号数的办法
在java中,整型的范围与运行java代码的机器无关
长整型数值有后缀L或l(如4000L)
十六进制数值有前缀0x或0X,二进制有前缀0b或0B,八进制有前缀0,为避免混淆,最好不要使用八进制常数,还可以为数字字面量加下划线来方便阅读,java编译器会自动去除(如1_000_000来表示1000000)
(2)浮点类型
- float——4字节
- double——8字节
double的数值精度是float的两倍,很少情况下适合使用float类型,例如使用单精度数的库,或者需要存储大量数据时
float后有后缀f或F,不然默认double
三个特殊的浮点数值,用于表示溢出和出错情况:正无穷大、负无穷大和NaN(不是一个数字),可以用Double.isNaN(x)来判断
(3)char类型
char类型的字面量值要用单引号括起来,如‘A’是编码值为65的字面常量,而“A”是一个包含A的字符串
char类型的值可以表示为十六进制值,其范围从\u0000到\uFFFF
\b是退格,\r是回车,\u是转义
(4)boolean类型
布尔类型有两个值:false和true,布尔类型不能和整数类型之间相互转换
2.常量
用final来指示常量
final Double CM = 2.54;
在java中,我们经常希望某个常量可以在一个类的多个方法中使用,通常将这些常量称之为类常量,可以用static final来设置类常量
public static final Double CM = 2.54;
类常量的定义要放在main方法的外部,如果被声明为public,那么其他类的方法也可以使用
3.运算符
(1)算术运算符
当参与“/”运算的两个操作数都是整数时,表示整数除法,否则,表示浮点除法
(2)数学函数与常量
- Math.sqrt()求平方根
- Math.pow()求幂————两个操作数都是Double类型,返回值也是Double类型
- Math.floorMod()取模————“%”是向0的方向取整,如-3.333会取成-3,而floorMod会向无穷小的方向取整:-3.333会取成-4
(3)数值类型之间的转换
- 无信息丢失的转换:byte->short->int->long、int->double、char->int、float->double
- 可能有精度损失的转换:int->float、long->float、long->double
(4)强制类型转换
强制类型转换将会截断小数点后的数
如果想对浮点数进行舍入运算,以便得到最接近的整数,可以用Math.round(),但是round返回的是long类型,所以需要强制类型转换为int
不要将布尔类型与任何类型做转换,极少数情况下才会用到,此时可以用b ? 1 : 0
(5)关系和boolean运算符
&&与 ||或 !非
很有用的三元操作符“?:”——
a > b ? a : b
为真运算第一个表达式,为假运算第二个表达式,例子将会返回一个a与b中最大的一个数
4.字符串
java没有内置的字符串类型,每个字符串都是String类的一个实例
(1)子串
String类的substring方法可以从一个额较大的字符串中提取出一个字串
String greeting = "Hello";
String s = String.substring(0,3);
这将会返回字符串“Hel”(左闭右开)
s的长度为3-0=3,这种方法方便计算子串长度
(2)拼接
允许用“+”来拼接两个字符串
当一个字符串与非字符串连接,后者会转换成字符串
如果需要把多个字符串放在一起,用一个界定符分隔,可以使用静态join方法:
String all = String.join("/","S","M","L","XL");
结果为“S/M/L/XL”
在java11中,可以通过String repeated = “java”.repeat(3);来得到结果“javajavajava”
(3)不可变字符串
永远无法改变java字符串中的单个字符,所以说String类对象被称为是不可变的。不过,可以修改字符串变量,让他引用另一个字符串,如下例:
greeting = greeting.substring(0,3) + "p!";
这样就可以将"Hello"修改为“Help!”
编译器可以让字符串共享。可以想象将各种字符串存放在公共的存储池中,字符串变量指向存储池中相应的位置;如果复制一个字符串变量,原始字符串与复制的字符串共享相同的字符。另,java会自动地进行垃圾回收,所以不会产生内存泄漏
(4)检测字符串是否相等
用equals方法来判断两个字符串是否相等,s.equals(t),s和t可以是字符串变量,也可以是字符串字面量
要检测两个字符串是否相等,而不区分大小写,用equalsIgnoreCase方法
(4)空串与Null串
空串是一个java对象,有自己的串长度(0)和内容(空),不过,String变量还可以存放一个特殊的值,名叫null,表示目前没有任何对象与该对象关联,可以用if(str == null)来检查一个字符串是否为null
(5)码点与代码单元
char数据类型是一个采用UTF-16编码表示Unicode码点的代码单元,辅助字符则需要一对代码单元来表示
length方法将返回代码单元数量,想要得到码点数量,则要调用
int cpCount = greeting.codePointCount(0, greeting.length())
调用s.charAt(n)将返回位置n的代码单元,而想得到第i个码点,则需要
int index = greeting.ofsetByCodePoints(0, i);
int cp = greeting.codePointAt(index);
如果想要遍历一个字符串,并且以此查看每个码点,可以用
int cp = sentence.codePointAt(i);
if(Character.isSupplementaryCodePoint(cp)) i +=2;
else i++;
更简单的是用codePoints方法
int[] codePoints = str.codePoints().toArray();
这会生成一个int值的“流”,每个int值对应一个码点,把它转换为一个数组,再完成遍历
反之,要把一个码点数组转换为一个字符串,可以使用构造器:
String str = new String(codePoints, 0, codePoints.length);
若想返回一个新字符串,且将大写变为小写或小写变为大写,可以用toLowerCase()和toUpperCase()方法
(6)构建字符串
若想增加效率,每次需要由较短的字符串构建字符串,可以考虑使用StringBuilder类
先构建一个空的字符串构建器:
StringBuilder builder = new StringBuilder();
每次需要添加一部分内容时,调用append方法
builder.append(ch);
builder.append(str);
构建完成时调用toString方法,将可得到一个String对象
String ans = builder.toString();
若想插入一个字符串或删除:
builder.insert(2, "zzz");
builder.delete(2, 3)
若想修改代码单元(注意是单引号的char类型)
builder.setCharAt(3, 'x')
4.输入与输出
(1)格式化输出
System.out.printf("%8.2f", x);
这会打印x:包括8个字符,精度为小数点后2个字符,若原始值是3333.33333333,则会打印出 3333.33,包括前导的一个空格
(2)文件输入与输出
暂略
5.大数
java.math中有两个可以处理包含任意长度数字序列的数值的类:BigInteger和BigDecimal
将普通的数值转换为大数:
BigInteger a = BigInteger.valueOf(100);
对于更大的数,可以使用一个带字符串参数的构造器:
BigInteger a = new BigInteger("22548666666666655555555555555555");
不能使用算术运算符来处理大数,而需要一些方法
BigInteger:
- add——加
- subtract——减
- multiply——乘
- divide——商
- mod——余数
- sqrt——平方根
- compareTo——比较是否相等
BigDecimal:
- add——加
- subtract——减
- multiply——乘
- divide——商
- compareTo——比较是否相等
divide若想得到一个舍入的结果,需要在后面加参数,如Rounding.HALF_UP是四舍五入
以下是一些学习用代码:
import java.math.*;
import java.util.*;
public class big{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String aaa = in.next();
int bbb = in.nextInt();
BigInteger bigtry = new BigInteger(aaa);
BigInteger inttry = BigInteger.valueOf(bbb);
BigDecimal dec2 = BigDecimal.valueOf(bbb);
BigDecimal dec1 = new BigDecimal(aaa);
System.out.println(dec1.divide(dec2,RoundingMode.HALF_UP)); //四舍五入,不加会报错
System.out.println(bigtry);
System.out.println(inttry);
System.out.println(bigtry.compareTo(inttry));
System.out.println(bigtry.subtract(inttry));
System.out.println(bigtry.mod(inttry));
System.out.println(bigtry.divide(inttry));
}
}
6.数组
(1)声明数组及访问数组元素
数字数组所有元素都会初始化为0,布尔数组的元素会初始化为false,对象数组的元素会初始化为一个特殊值null,表示这些元素还未存放任何对象,如
String[] names = new String[10];
这样所有字符串都会为null
要想获得数组中的元素个数,可以使用array.length
import java.util.*;
public class _arrays {
public static void main(String[] args) {
int[] a1 = new int[100];
// 匿名数组,可以用该方法重新初始化一个数组而无需创建新变量
int[] a2 = new int[] {45,47,46,57,41,36,};
// 最后一个值后面允许有逗号,方便后续添加
int[] a3 = {65,57,21,39,47,11,};
// 快速的打印数组中所有的值
System.out.println(Arrays.toString(a1));
// foreach,循环输出某数组的每一个元素,一个元素占一行
for(int b : a2)
System.out.println(b);
}
}
(2)数组拷贝
import java.util.*;
public class _arrays2 {
public static void main(String[] args) {
int[] arr1 = new int[10];
int[] arr2 = new int[10];
// arr1 = arr2; // 此时两个变量将引用同一个数组
// arr1[5] = 666;
// System.out.println(arr2[5]);
// 将一个数组的值拷贝到新数组中去
arr2 = new int[] {5,4,9,8,3,2,1,6,1,7};
arr1 = Arrays.copyOf(arr2, arr2.length*2); // 第二个参数是新数组的长度,通常可以用来增加数组长度
Arrays.sort(arr1);
for(int b : arr1)
System.out.println(b);
}
}
(3)一个简单的抽彩游戏
import java.util.*;
//输入最大值与所需值的个数,从中随机挑选所需个数
public class _arrays_bet {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int k = in.nextInt();
int[] numbers = new int[n];
for(int i = 0; i < numbers.length; i++) {
numbers[i] = i + 1;
}
int[] result = new int[k];
for(int i = 0; i < result.length; i++) {
int r = (int)(Math.random() * n);
result[i] = numbers[r];
numbers[r] = numbers[n-1];
n = n - 1;
}
Arrays.sort(result);
for(int b : result)
System.out.println(b);
}
}
(4)一些零散的知识点
import java.util.*;
public class _arrays3 {
public static void main(String[] args) {
int[] arr1 = new int[100];
int[] arr2 = new int[100];
for(int i = 0; i < 100; i++) {
arr1[i] = i;
}
// Arrays.fill(arr1,100); // 将数组所有元素设置为某一值
// 二分查找在数组中寻找某一值,若有返回下标,若没有返回一个负值,-r-1为该数应按序插入的位置,中间可以有两个参数代表查找的范围,左闭右开
System.out.println(Arrays.binarySearch(arr1,40, 50, 49));
for(int b : arr1)
System.out.println(b);
// 返回跟某数组一样类型的数组,元素也一样,长度自定义,copyOfRange可以用来精确定义长度,copyOf只能返回长度为length或对length修改的
arr2 = Arrays.copyOfRange(arr1, 10, 20);
for(int c : arr2)
System.out.println(c);
}
}
(5)二维数组
for each循环语句处理二维数组时,会先循环处理行,而这些行本身就是一维数组,所以需要嵌套循环
import java.util.*;
public class _2Darray {
public static void main(String[] args) {
int num = 0;
// 数组的初始化要么用new,要么给出数组元素,注意有两个大括号
int[][] balance = new int[5][10];
int[][] balance1 =
{
{6,5,4,7},
{6,8,7,3},
{3,5,1,2}
};
// 数组的长度:balance.length表示的是行数,balance[x].length表示的是第x行的列数
for(int i = 0; i < balance.length; i++) {
for(int j = 0; j < balance[i].length; j++) {
balance[i][j] = num + 1;
num = num + 1;
}
}
// 二维数组的输出有两种方式,一种用for each嵌套循环,先循环处理行,而这些行本身就是数组。第二种用deepToString方法快速打印出一个数据元素列表
for(int[] b : balance) {
for(int c : b) {
System.out.print(c + " ");
}
System.out.println();
}
System.out.println(Arrays.deepToString(balance));
// 这样可以实现行与行的交换
int[] temp = balance[2];
balance[2] = balance[3];
balance[3] = temp;
}
}
下面是不同利率下的投资
import java.util.*;
public class _2DarrayTest {
public static void main(String[] args) {
final double STARTRATE = 10;
final int NRATES = 6;
final int NYEARS = 10;
double[] interestRate = new double[NRATES];
for(int j = 0; j < interestRate.length; j++) {
interestRate[j] = (STARTRATE + j) / 100.0;
}
double[][] balances = new double[NYEARS][NRATES];
for(int j = 0; j < balances[0].length; j++) {
balances[0][j] = 10000;
}
for(int i = 1; i < balances.length; i++) {
for(int j = 0; j < balances[i].length; j++) {
double oldBalance = balances[i - 1][j];
double interest = oldBalance * interestRate[j];
balances[i][j] = oldBalance + interest;
}
}
for(int j = 0; j < interestRate.length; j++) {
System.out.printf("%9.0f%%", 100 * interestRate[j]);
}
System.out.println();
for(double[] row : balances) {
for(double b : row)
System.out.printf("%10.2f", b);
System.out.println();
}
}
}
(6)不规则数组
java实际上没有多维数组,只有一维数组,多维数组被解释为“数组的数组”。如一个二维数组balances[10][6],实际上是一个包含10个元素的数组,而每个元素又是一个由6个数组成的数组
表达式balance[i]引用第i个数组,也就是表格的第i行
import java.util.*;
public class JaggedTry {
public static void main(String[] args) {
final int NMAX = 10;
int num = 1;
// 先初始化行数,不初始化没法用
int[][] arr1 = new int[NMAX + 1][];
// 对每行,即每个数组分配子数组,即初始化它们的列
for(int i = 0; i <= NMAX; i++)
arr1[i] = new int[i + 3];
for(int i = 0; i<arr1.length; i++) {
for(int j = 0; j < arr1[i].length; j++) {
arr1[i][j] = num;
num++;
}
}
for(int[] b : arr1) {
for(int c : b)
System.out.printf("%4d", c);
System.out.println();
}
}
}
以下程序演示了构建一个三角形数组
import java.util.*;
public class Jagged_triangularArray {
public static void main(String[] args) {
final int NMAX = 10;
int[][] odds = new int[NMAX + 1][];
for(int n = 0; n <= NMAX; n++)
odds[n] = new int[n + 1];
for(int n = 0; n < odds.length; n++) {
for(int k = 0; k < odds[n].length; k++) {
int lotteryOdds = 1;
for(int i = 1; i <=k; i++)
lotteryOdds = lotteryOdds * (n - i + 1) / i;
odds[n][k] = lotteryOdds;
}
}
for(int[] row : odds) {
for(int odd : row)
System.out.printf("%4d", odd);
System.out.println();
}
}
}
posted on
浙公网安备 33010602011771号