Java核心技术 卷1 Ch.3

Ch.III Java基本程序设计结构:

  1. Java区分大小写

  2. 一个标准的程序格式:

    public class FirstSample{
    	public static void main(String[] args){
    	System.out.println("We will not use 'Hello, World!"') ;
    	} //This is a 注释
    }
    
    • public:

      称之为访问修饰符, 用于控制程序的其他部分对这段代码的访问级别

    • FirstSample:

      类名, 具体的定义规则和C++相同

      注意: 这里的类名必须和源代码的文件名相同, 且必须区分大小写!

      这里使用.Java作为文件的扩展名, 相当于C++的.cpp文件
      而编译产生的文件扩展名为.class, 为类字节码文件, 相当于输出的.exe

    • 与C++相同, Java中也需要一个main

      当运行.class文件时, 将会定位到main处开始运行

    • 与C++相同, Java中也是使用{ }标注代码块

    • 与C++相同, Java也会忽略源文件中的所有空白字符, 所以可以像C++一样自由的排版

    • 与C++相同, Java中的注释方法也是一样的, 使用///**/ 进行!

      但是有一点不同, Java中可以使用/**可以构建注释文档, 其实就是由编译器自动生成每行的注释, 便于书写!

  3. 关于Java的类与C++的类的区别:

Java中, 所有的类中的函数并不成为成员函数, 官方称之为方法

所以main需要一个包装的外壳类

  1. Java基本数据类型:

大部分和C++相同

不同之处:

  • 没有unsigned整型

  • 没有bool类型, 代替的是boolean

  • Java中所有的数据类型都和机器无关(不像C++中的int和16位与32位机器相关)

  • Java中没有声明变量, 而C++中使用extern声明一个外部变量:

    extern int a;
    
  • Java中使用final表示常量, 而C++中使用const

    Java中的const有另外的用途, 现在还没有学到

  • C++中的char固定占用1个字节, 而Java中的Char占用的是1~6个字节, 具体视编码而定
    但通常是2个字节

Java中特有操作:

  • 3个特殊的浮点值:

    正无穷大, 负无穷大, NaN

    分别用Double_POSITIVE_INFINITY、 Double.NEGATIVEJNFINITY 和 Double.NaN 表示
    注意这里的Double是大写

  • 稀有关键字: strictfp

    如果你想让你的浮点运算更加精确,而且不会因为不同的硬件平台所执行的结果不一致的话,可以用关键字strictfp.

    但是严格计算将会花费更多的时间, 并且有可能导致溢出

  • 不要在Boolean与其他任何类型之间发生类型转换

  1. 关于C++中的include头文件在Java中的映射:

    Java中并没有include头文件的方法, 想要使用相关的函数, 有两个方法:

    • 直接调用相关的类:

      如使用Math中的函数sqrt:

      double x = 4;
      double y = Math.sqrt(x);	//直接像调用类的成员函数一样使用
      System.out.println(y); 		// prints 2.0
      
    • 或是在文件头中使用import:

      import static java.lang.Math.*
      

      这里具体的使用放到后头进行

  2. Java中的字符串:

可以使用String类储存字符串, 具体的操作和C++的string相似

  • 相似处:

    支持String的+拼接等操作

    支持使用=进行重新赋值

    存在空串和null串, 其中空串相当于指向长度为0的字符串, 而null相当于null指针( 不指向任何内存空间)

  • 不同:

    1. String对象是静态类型:
    
    Java的字符串实际上相当于C++ 中的char*字符串指针, 指向存放在程序静态部分的字符, ==所以Java中的String对象是不可修改的final静态类型==, 即**不可对字符串中的单个字符进行修改**
    
    
    2. String对象在重新赋值时不必担心内存泄漏:
    
    Java与C++的一大不同之处就是Java的内存回收机制, 一段内存不在使用后, 会被系统自动回收
    
    
    3. 不支持使用==进行检测判定
    
    没有重载这个运算符
    
  1. Java中的String类型的每个char占用2个字节, 并且如果编码不同, char占用的字节数也会改变, 所以:
```java
str.lenth(); 	//返回的是str的代码单元数
	
//而想要返回str真正的字符数, 需要使用:
str.codePointCount(0,str.lenth());	//从0开始计数, 计算str中的码点数(字符数)
```

而获取第i个码点, 即第i个字节处的数据, 需要使用:

```java
str.codePointAt(i);	//将返回第i个字节处的数值, 返回类型为int
```

**拓展: Unicode代码点&代码单元**

需要了解一下Unicode的编码方式:

- UTF-8: 使用1~4个字节的表示一个字符
- UTF-16: 使用2个字节表示基本多语言平面字符,4个字节表示辅助平面字符
- UTF-32: 使用4个字节表示一个字符
  • 代码点: 表示Unicode的一个字符的码值

  • 代码单元: 16bit表示一个代码单元

而Java中的char基本类型以及String使用的都是UTF-16编码, 所以如果使用String储存中文, 每个中文字符占用16bit, 即代码点数=代码单元数

但是如果储存emoji, 就需要32bit, 此时代码点数=代码单元数*2

**以下为一个小小的例子:**

```java
public class Welcome {
    public static void main(String[] args) {
        String chineseTest="微软垃圾";
        System.out.println(chineseTest);
        System.out.println(chineseTest.length());
        System.out.println(chineseTest.codePointCount(0,chineseTest.length()));
        String emojiTest="\uD83D\uDE1D";
        System.out.println(emojiTest);
        System.out.println(emojiTest.length());
        System.out.println(emojiTest.codePointCount(0,emojiTest.length()));
    }
}
```

输出结果:

>![image-20200119170159813](C:\Users\Janus II\AppData\Roaming\Typora\typora-user-images\image-20200119170159813.png)





拓展: 多个字符串快速拼接的方法:

使用String的方法join:

```java
String all = String.join(" / ", "S", "M", "L", "XL");
// all is the string "S / H / L / XL"
```

**拓展: 检测字符串是否相等**

使用equals:

```java
  str.equals(t); 	//区分大小写
  "Hello".equalsIgnoreCase("hel1o");   
```

Java String API:

	char charAt(int index) 
//返回 char指定索引处的值。  

    int codePointAt(int index) 
//返回指定索引处的字符(Unicode代码点)。  

    int codePointBefore(int index) 
//返回指定索引之前的字符(Unicode代码点)。  

    int codePointCount(int beginIndex, int endIndex) 
//返回此 String指定文本范围内的Unicode代码点数。  

    int compareTo(String anotherString) 
//按字典顺序比较两个字符串。  

    int compareToIgnoreCase(String str) 
//按字典顺序比较两个字符串,忽略病例差异。  

    String concat(String str) 
//将指定的字符串连接到该字符串的末尾。  

    boolean contains(CharSequence s) 
//当且仅当此字符串包含指定的char值序列时才返回true。  

    boolean contentEquals(CharSequence cs) 
//将此字符串与指定的CharSequence进行 CharSequence 。  

    boolean contentEquals(StringBuffer sb) 
//将此字符串与指定的StringBuffer进行 StringBuffer 。  

    static String copyValueOf(char[] data) 
//相当于 valueOf(char[]) 。  

    static String copyValueOf(char[] data, int offset, int count) 
//相当于 valueOf(char[], int, int) 。  

    boolean endsWith(String suffix) 
//测试此字符串是否以指定的后缀结尾。  

    boolean equals(Object anObject) 
//将此字符串与指定对象进行比较。  

    boolean equalsIgnoreCase(String anotherString) 
//将此 String与其他 String比较,忽略案例注意事项。  

    static String format(Locale l, String format, Object... args) 
//使用指定的区域设置,格式字符串和参数返回格式化的字符串。  

    static String format(String format, Object... args) 
/使用指定的格式字符串和参数返回格式化的字符串。  

    byte[] getBytes() 
//使用平台的默认字符集将此 String编码为字节序列,将结果存储到新的字节数组中。  

    byte[] getBytes(Charset charset) 
//使用给定的charset将该String编码为字节序列,将结果存储到新的字节数组中。  

    void getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin) 
//已弃用 
//此方法无法将字符正确转换为字节。 从JDK 1.1开始,首选的方法是通过getBytes()方法,该方法使用平台的默认字符集。  

    byte[] getBytes(String charsetName) 
//使用命名的字符集将此 String编码为字节序列,将结果存储到新的字节数组中。  

    void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) 
//将此字符串中的字符复制到目标字符数组中。  

    int hashCode() 
//返回此字符串的哈希码。  

    int indexOf(int ch) 
//返回指定字符第一次出现的字符串内的索引。  

    int indexOf(int ch, int fromIndex) 
//返回指定字符第一次出现的字符串内的索引,以指定的索引开始搜索。  

    int indexOf(String str) 
//返回指定子字符串第一次出现的字符串内的索引。  

    int indexOf(String str, int fromIndex) 
//返回指定子串的第一次出现的字符串中的索引,从指定的索引开始。  

    String intern() 
//返回字符串对象的规范表示。  

    boolean isEmpty() 
//返回 true如果,且仅当 length()为 0 。  

    static String join(CharSequence delimiter, CharSequence... elements) 
//返回一个新的字符串,由 CharSequence elements的副本组成,并附有指定的delimiter的 delimiter 。  

    static String join(CharSequence delimiter, Iterable<? extends CharSequence> elements) 
//返回一个新 String的副本组成 CharSequence elements与指定的副本一起加入 delimiter 。  

    int lastIndexOf(int ch) 
//返回指定字符的最后一次出现的字符串中的索引。  

    int lastIndexOf(int ch, int fromIndex) 
//返回指定字符的最后一次出现的字符串中的索引,从指定的索引开始向后搜索。  

    int lastIndexOf(String str) 
//返回指定子字符串最后一次出现的字符串中的索引。  

    int lastIndexOf(String str, int fromIndex) 
//返回指定子字符串的最后一次出现的字符串中的索引,从指定索引开始向后搜索。  

    int length() 
//返回此字符串的长度。  

    boolean matches(String regex) 
//告诉这个字符串是否匹配给定的 regular expression 。  

    int offsetByCodePoints(int index, int codePointOffset) 
//返回此 String内的指数,与 index codePointOffset代码点。  

    boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) 
//测试两个字符串区域是否相等。  

    boolean regionMatches(int toffset, String other, int ooffset, int len) 
//测试两个字符串区域是否相等。  

    String replace(char oldChar, char newChar) 
//返回从替换所有出现的导致一个字符串 oldChar在此字符串 newChar 。  

    String replace(CharSequence target, CharSequence replacement) 
//将与字面目标序列匹配的字符串的每个子字符串替换为指定的字面替换序列。  

    String replaceAll(String regex, String replacement) 
///用给定的替换替换与给定的 regular expression匹配的此字符串的每个子字符串。  

    String replaceFirst(String regex, String replacement) 
//用给定的替换替换与给定的 regular expression匹配的此字符串的第一个子字符串。  

    String[] split(String regex) 
//将此字符串分割为给定的 regular expression的匹配。  

    String[] split(String regex, int limit) 
//将这个字符串拆分为给定的 regular expression的匹配。  

    boolean startsWith(String prefix) 
//测试此字符串是否以指定的前缀开头。  

    boolean startsWith(String prefix, int toffset) 
//测试在指定索引处开始的此字符串的子字符串是否以指定的前缀开头。  

    CharSequence subSequence(int beginIndex, int endIndex) 
//返回一个字符序列,该序列是该序列的子序列。  

    String substring(int beginIndex) 
//返回一个字符串,该字符串是此字符串的子字符串。  

    String substring(int beginIndex, int endIndex) 
//返回一个字符串,该字符串是此字符串的子字符串。  

    char[] toCharArray() 
//将此字符串转换为新的字符数组。  

    String toLowerCase() 
//将所有在此字符 String使用默认语言环境的规则,以小写。  

    String toLowerCase(Locale locale) 
//将所有在此字符 String ,以降低使用给定的规则情况下 Locale 。  

    String toString() 
//此对象(已经是字符串!)本身已被返回。  

    String toUpperCase() 
//将所有在此字符 String使用默认语言环境的规则大写。  

    String toUpperCase(Locale locale) 
//将所有在此字符 String使用给定的规则,大写 Locale 。  

    String trim() 
//返回一个字符串,其值为此字符串,并删除任何前导和尾随空格。  

    static String valueOf(boolean b) 
//返回 boolean参数的字符串 boolean形式。  

    static String valueOf(char c) 
//返回 char参数的字符串 char形式。  

    static String valueOf(char[] data) 
//返回 char数组参数的字符串 char形式。  

    static String valueOf(char[] data, int offset, int count) 
//返回 char数组参数的特定子阵列的字符串 char形式。  

    static String valueOf(double d) 
//返回 double参数的字符串 double形式。  

    static String valueOf(float f) 
//返回 float参数的字符串 float形式。  

    static String valueOf(int i) 
//返回 int参数的字符串 int形式。  

    static String valueOf(long l) 
//返回 long参数的字符串 long形式。  

    static String valueOf(Object obj) 
//返回 Object参数的字符串 Object形式。  

3.7基础输入输出:

读取输入:

输入流主要使用Scanner类

scanner相当于一个光标, 扫描输入的文本
使用不同的Scanner方法将光标下一个输入解释为不同的数据类型, 如果输入的数据类型有误, 则会报错

关于报错:

具体的报错内容如下, 内部逻辑暂时未知:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YWxJCWSa-1579572051910)(C:\Users\Janus II\AppData\Roaming\Typora\typora-user-images\image-20200116201102918.png)]

使用Scanner前需要先定义Scanner对象
通常使用new创建新对象:

Scanner inputString=new Scanner(System.in);

有两套常用的方法:

  1. next系列:

    根据所需要的数据类型, 使用相应的方法, 读取下一个数据, 如果数据类型不符, 则会报错, 相当于程序异常终止

  2. has系列:

    用于判断光标的下一个输入的数据类型, 使用相应的方法判定下一个输入是否属于相应的数据类型, 返回类型为boolern

以下是Scanner类的API:

void close() 
//关闭此扫描仪。  

Pattern delimiter() 
//返回 Pattern这个 Scanner正在使用来匹配分隔符。  

String findInLine(Pattern pattern) 
//尝试找到忽略分隔符的指定模式的下一个出现。  

String findInLine(String pattern) 
//尝试查找从指定字符串构造的模式的下一个出现,忽略分隔符。  

String findWithinHorizon(Pattern pattern, int horizon) 
//尝试找到指定模式的下一个出现。  

String findWithinHorizon(String pattern, int horizon) 
//尝试查找从指定字符串构造的模式的下一个出现,忽略分隔符。  

boolean hasNext() 
//如果此扫描仪在其输入中有另一个令牌,则返回true。  

boolean hasNext(Pattern pattern) 
//如果下一个完整的令牌匹配指定的模式,则返回true。  

boolean hasNext(String pattern) 
//如果下一个令牌匹配从指定字符串构造的模式,则返回true。  

boolean hasNextBigDecimal() 
//如果在此扫描器输入信息的下一个标记可以解释为,则返回true BigDecimal使用 
nextBigDecimal()方法。  
boolean hasNextBigInteger() 

//如果在此扫描器输入信息的下一个标记可以解释为,则返回true BigInteger在使用默认基数 nextBigInteger()方法。  

boolean hasNextBigInteger(int radix) 
//如果在此扫描器输入信息的下一个标记可以解释为,则返回true BigInteger在使用指
定基数 nextBigInteger()方法。  
boolean hasNextBoolean() 

//如果此扫描器输入中的下一个标记可以使用从字符串“true | false”创建的不区分大小写的模式解释为布尔值,则返回true。  

boolean hasNextByte() 
//如果此扫描仪输入中的下一个标记可以使用 nextByte()方法将其 解释为默认基数中的
字节值,则返回trueboolean hasNextByte(int radix) 
//如果扫描仪输入中的下一个标记可以使用 nextByte()方法解释为指定基数中的字节
值,则返回trueboolean hasNextDouble() 
//如果扫描仪的输入中的下一个标记可以使用 nextDouble()方法将其解释为双重值,则返回true。  

boolean hasNextFloat() 
//如果扫描仪输入中的下一个标记可以使用 nextFloat()方法将其解释为浮点值,则返回true。  

boolean hasNextInt() 
//如果此扫描仪输入中的下一个标记可以使用 nextInt()方法解释为默认基数中的int值,则返回true。  

boolean hasNextInt(int radix) 
//如果此扫描仪输入中的下一个标记可以使用 nextInt()方法解释为指定基数中的int值,则返回true。  

boolean hasNextLine() 
//如果扫描仪的输入中有另一行,则返回true。  

boolean hasNextLong() 
//如果此扫描仪输入中的下一个标记可以使用 nextLong()方法将其 解释为默认基数中的长整型值,则返回true。  

boolean hasNextLong(int radix) 
//如果扫描仪的输入中的下一个标记可以使用 nextLong()方法解释为指定基数中的长整型值,则返回true。  

boolean hasNextShort() 
//如果此扫描仪输入中的下一个标记可以使用 nextShort()方法将其 解释为默认基数中的一个短值,则返回true。  

boolean hasNextShort(int radix) 
//如果扫描仪的输入中的下一个标记可以使用 nextShort()方法解释为指定基数中的一个短值,则返回true。  

IOException ioException() 
//返回 IOException最后通过此抛出 Scanner的基本 Readable 。  

Locale locale() 
//返回此扫描仪的区域设置。  

MatchResult match() 
//返回此扫描仪执行的最后扫描操作的匹配结果。  

String next() 
//查找并返回此扫描仪的下一个完整令牌。  

String next(Pattern pattern) 
//如果匹配指定的模式,则返回下一个令牌。  

String next(String pattern) 
//如果匹配从指定字符串构造的模式,则返回下一个令牌。  

BigDecimal nextBigDecimal() 
//将输入的下一个标记扫描为BigDecimal 。  

BigInteger nextBigInteger() 
//将输入的下一个标记扫描为BigInteger 。  

BigInteger nextBigInteger(int radix) 
//将输入的下一个标记扫描为BigInteger 。  

boolean nextBoolean() 
//将输入的下一个标记扫描为布尔值,并返回该值。  

byte nextByte() 
//将输入的下一个标记扫描为 byte 。  

byte nextByte(int radix) 
//将输入的下一个标记扫描为 byte 。  

double nextDouble() 
//将输入的下一个标记扫描为 double 。  

float nextFloat() 
//将输入的下一个标记扫描为 float 。  

int nextInt() 
//将输入的下一个标记扫描为 int 。  

int nextInt(int radix) 
//将输入的下一个标记扫描为 int 。  

String nextLine() 
//将此扫描仪推进到当前行并返回跳过的输入。  

long nextLong() 
//将输入的下一个标记扫描为 long 。  

long nextLong(int radix) 
//将输入的下一个标记扫描为 long 。  

short nextShort() 
//将输入的下一个标记扫描为 short 。  

short nextShort(int radix) 
//将输入的下一个标记扫描为 short 。  

int radix() 
//返回此扫描仪的默认基数。  

void remove() 
//Iterator的此实现不支持删除 Iterator 。  

Scanner reset() 
//重设此扫描仪。  

Scanner skip(Pattern pattern) 
//跳过与指定模式匹配的输入,忽略分隔符。  

Scanner skip(String pattern) 
//跳过与指定字符串构成的模式匹配的输入。  

String toString() 
//返回此 Scanner的字符串表示 Scanner 。  

Scanner useDelimiter(Pattern pattern) 
//将此扫描仪的分隔模式设置为指定的模式。  

Scanner useDelimiter(String pattern) 
//将此扫描器的分隔模式设置为从指定的构造的模式 String 。  

Scanner useLocale(Locale locale) 
//将此扫描仪的区域设置设置为指定的区域设置。  
Scanner useRadix(int radix) 
//将此扫描仪的默认基数设置为指定的基数。  

拓展: 关于不可见输入, 如密码输入:

Java SE 6 中引入Console类实现这个功能:

Console cons = System.console();
String username = cons.readLine("User name: ");
char [] passwd = cons.readPassword("Password: ");
System.out.println(passwd);

由于需要在cmd控制台环境下运行才能有效, 所以暂时无法测试

格式化输出:

在Java SE 5中引入了C语言的printf方法, 所以格式化输出会非常 的方便

Java中的printf与C语言非常的相似, 这里就不多做阐述了

而C++的cout方法可以通过System. out. printIn解决

文件输入输出:

文件输入:
Scanner in= new Scanner(Paths.get("myfile.txt"),"UTF-8");

也是使用Scanner类, 但是使用的是含有文件路径的构造函数

  • Paths.get获取的是目标文件的路径

    Scanner(File f)
    //构造一个从给定文件读取数据的 Scanner 
    

    注意这里不能直接使用文件名, 编译器会将其解释为数据而不是文件名, 所以打不开文件

    使用的构造函数就变成了这个:

    Scanner(String data)
    //构造一个从给定字符串读取数据的 Scanner。
    
  • UTF-8是文件的编码方式

    当没有指定文件的编码方式时, Java将使用默认的编码方式, 不同机器有不同的结果

说明:
如果文件路径中包含反斜杠, 则应该使用双反斜杠

文件输出:
PrintWriter out = new Printlulriter("myfile.txt", "UTF-8");

如果文件不存在, 则会创建该文件

API:

static Path get(String pathname)
//根据给定的路径名构造一个 Path

3.8控制流程:

本部分实际上就是C++的逻辑控制部分, 没啥特点, 这里仅仅记录不一样的部分:

  1. Java没有goto语句

  2. break可以带标签

    由此实现跳出多层循环的功能

    但是具体的使用方法和goto不同
    其中标签放在想要跳出的循环的代码块的最前头, 而后break会直接跳到此代码块的结尾

    这里的就和goto不同了

    这样设计的原因是防止将break当成goto使用

    read_data:
    while (. . .) // this loop statement is tagged with the label
    for (. . .) // this inner loop is not labeled
    {
    Systen.out.print("Enter a number >= 0: ");
    n = in.nextlntO;
    if (n < 0) // should never happen-can’t go on
    break read
    .
    data;
    // break out of readjata loop
    }
    
  3. Java中不允许同名变量的覆盖
    即不允许内层块含有与外层块相同名称的变量

    在C++中, 这种行为虽然是允许的, 但是也是素质极差的习惯, 所以Java索性将其列为Error

3.9大数值:

C++中需要手写大数计算方法, 但是Java中的math包中提供了相应的方法:

  • BigInteger: 用于计算任意长度的整数
  • BigDecimal: 用于计算任意精度的浮点数

使用方法为调用相应类的方法来实现

由于Java中没有重载运算符, 所以只能使用方法

通常使用的方法:

  • 通过构造函数创建需要计算的数值
  • 调用相应的方法完成计算
Biglnteger c = a.add(b); 
// c = a + b

Biglnteger d = c.nulti piy(b.add(Biglnteger.val ueOf(2))); 
// d = c * (b + 2)

这里直接给出这俩的API:

  1. BigInteger:

    构造函数:

    BigInteger(byte[] val) 
    //将包含BigInteger的二进制补码二进制表达式的字节数组转换为BigInteger。  
    
    BigInteger(int signum, byte[] magnitude) 
    //将BigInteger的符号大小表示形式转换为BigInteger。  
    
    BigInteger(int bitLength, int certainty, Random rnd) 
    //构造一个随机生成的正BigInteger,它可能是素数,具有指定的bitLength。  
    
    BigInteger(int numBits, Random rnd) 
    //构造一个随机生成的BigInteger,均匀分布在0到(2 numBits - 1)的范围内。  
    
    BigInteger(String val) 
    //将BigInteger的十进制字符串表示形式转换为BigInteger。  
    
    BigInteger(String val, int radix) 
    //将指定基数中的BigInteger的String表示形式转换为BigInteger。  
    

    常用の方法:

    Biglnteger add(Biglnteger other)
    
    Biglnteger subtract(Biglnteger other)
    
    Biglnteger multipiy(Biginteger other)
    
    Biglnteger divide(Biglnteger other)
    
    Biglnteger mod(Biglnteger other)
    //返冋这个大整数和另一个大整数 other的和、 差、 积、 商以及余数。
    
    int compareTo(Biglnteger other)
    //如果这个大整数与另一个大整数 other 相等, 返回 0; 如果这个大整数小于另一个大整数 other, 返回负数; 否则, 返回正数。
    
    static Biglnteger valueOf(1ong x)
    //返回值等于 x 的大整数。
    

  2. BigDecimal:

    构造函数:

    BigDecimal(BigInteger val) 
    //将 BigInteger转换成 BigDecimal 。  
    
    BigDecimal(BigInteger unscaledVal, int scale) 
    //将BigInteger的 BigInteger值和 int等级转换为 BigDecimal 。  
    
    BigDecimal(BigInteger unscaledVal, int scale, MathContext mc) 
    //将 BigInteger未缩放值和 int扩展转换为 BigDecimal ,根据上下文设置进行舍入。  
    
    BigDecimal(BigInteger val, MathContext mc) 
    //根据上下文设置将 BigInteger转换为 BigDecimal舍入。  
    
    BigDecimal(char[] in) 
    //一个转换的字符数组表示 BigDecimal成 BigDecimal ,接受字符作为的相同序列 BigDecimal(String)构造。  
    
    BigDecimal(char[] in, int offset, int len) 
    //一个转换的字符数组表示 BigDecimal成 BigDecimal ,接受字符作为的相同序列 BigDecimal(String)构造,同时允许一个子阵列被指定。  
    
    BigDecimal(char[] in, int offset, int len, MathContext mc) 
    //一个转换的字符数组表示 BigDecimal成 BigDecimal ,接受字符作为的相同序列 BigDecimal(String)构造,同时允许指定一个子阵列和用根据上下文设置进行舍入。  
    
    BigDecimal(char[] in, MathContext mc) 
    //一个转换的字符数组表示 BigDecimal成 BigDecimal ,接受相同的字符序列作为 BigDecimal(String)构造与根据上下文设置进行舍入。  
    
    BigDecimal(double val) 
    //将 double转换为 BigDecimal ,这是 double的二进制浮点值的精确十进制表示。  
    
    BigDecimal(double val, MathContext mc) 
    //将 double转换为 BigDecimal ,根据上下文设置进行舍入。  
    
    BigDecimal(int val) 
    //将 int成 BigDecimal 。  
    
    BigDecimal(int val, MathContext mc) 
    //将 int转换为 BigDecimal ,根据上下文设置进行舍入。  
    
    BigDecimal(long val) 
    //将 long成 BigDecimal 。  
    
    BigDecimal(long val, MathContext mc) 
    //将 long转换为 BigDecimal ,根据上下文设置进行舍入。  
    
    BigDecimal(String val) 
    //将BigDecimal的字符串表示 BigDecimal转换为 BigDecimal 。  
    
    BigDecimal(String val, MathContext mc) 
    //一个转换的字符串表示 BigDecimal成 BigDecimal ,接受相同的字符串作为 BigDecimal(String)构造,利用根据上下文设置进行舍入。  
    
    

    常用方法:

    BigDecimal add(BigDecimal other)
    
    BigDecimal subtract(BigDecimal other)
    
    BigDecimal multipiy(BigDecimal other)
    
    BigDecimal divide(BigDecimal other RoundingMode mode) 5.0
    //返回这个大实数与另一个大实数 other 的和、 差、 积、 商。
    //要想计算商, 必须给出舍入方式 ( rounding mode) 	
    //RoundingMode.HALF_UP 是在学校中学习的四舍五入方式( BP , 数值 0 到 4 舍去, 数值 5 到 9 进位)
    //它适用于常规的计算。有关其他的舍入方式请参看 Api文档。
    
    int compareTo(BigDecimal other)
    //如果这个大实数与另一个大实数相等, 返回 0 ; 如果这个大实数小于另一个大实数,返回负数; 否则,返回正数。
    
    static BigDecimal valueOf(1 ong x)
    
    static BigDecimal valueOf(1 ong x ,int scale)
    //返回值为 X 或 x / 10scale 的一个大实数。
    

3.10数组:

Java的数组声明格式和C++相似, 但是还有另一种方式:

int [] a= new int[n];
// Java风格, 大部分Java程序员采用的风格
//相当于声明了一个指针, 由于Java的垃圾回收机制, 使用起来和普通数组一样方便

int a[] = new int[n];
//C++风格
//但是与C++不同的是还是需要使用new申请内存

与C++的不同之处:

  1. 即时使用C++风格的数组定义方式, 也要使用new申请内存

  2. Java的数组创建时就被自动初始化为0值 (包括0, false, null), 无需进行手动的初始化

  3. Java的数组如果发生越界访问, 会抛出array index out of bounds异常, 导致程序异常退出

  4. Java中数组的实质更相当于C++中的指针

    intD a = new int[100]; // Java
    不同于
    int a[100]; // C++
    而等同于
    int* a = new int[100]; // C++
    

    且数组没有指针运算, 即无法通过a+1得到下一个元素

数组的初始化:

方法还是和C++相同的;

int [] arr = new int [] {0,1,2,3,4,5,6,7,8,9};
//同样支持让编译器计数

int [] arr ={0,1,2,3,4,5,6,7,8,9};
//简化的初始化方法


数组的快速输出:

两种方法:

  1. 使用for each (相当于C++的范围for)

    int[] a=new int[] {0,1,2,3,4,5,6,7,8,9};
    for (int temp: a){
        System.out.printf("%d ",temp);
    }
    
  2. 使用toString方法:

    System.out.println(Arrays.toString(a));
    

数组拷贝:

两种方法:

  1. 类似于C++中的浅拷贝, 利用Java数组的实质是指针的特性, 使得两个数组指向同一个内存片段

    intQ luckyNumbers = smallPrimes;
    luckyNumbers[S] = 12;
    // now smallPrimes[5] is also 12
    
  2. 使用Arrays类中的copyOf方法:

    int[] copiedLuckyNumbers = Arrays.copyOf(luckyNumbers, luckyNumbers.length) ;
    

    API如下:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6GfYJ5FQ-1579572051912)(C:\Users\Janus II\AppData\Roaming\Typora\typora-user-images\image-20200117173144499.png)]

数组排序:

同样是调用Arrays类的sort()方法

int[] a = new int[10000];
...
Arrays.sort(a);

类似于C++的STL库泛型算法, sort对不同类型的数据优化较好

API如下:

static void sort(type[] a)
//采用优化的快速排序算法对数组进行排序。

其中type是类似C++模板的东西, 支持的数据类型包括int , long, short, char, byte, boolean, float, double

二维数组&不规则数组:

主要利用了Java数组实际上为指针的特性

当创建二维数组时, 相当于创建了一个二级指针, 指向一个指针数组:

doublet] [] balances = new double[10] [6]; 
//不同于
double balances [10] [6] ; // C++
//也不同于
double (*balances) [6] = new double[10] [6] ; // C++
//而是分配了一个包含 10 个指针的数组:
double** balances = new double*[10] ; // C++

而由于指针数组中的每一个元素都可以独立赋值, 所以可以创建一个不规则数组

拓展: Java程序控制台运行:

与C++ 程序的区别就是:

  1. 程序名并没有包含在arg[] 中, 即arg[0]为第一个参数
  2. C++编译产生的文件为.exe可执行文件, 而Java编译产生的最终文件是.java字节码文件, 需要使用字节码解释器来运行

拓展: 随机数:

Java中的随机数函数在Math类中:

static double random() 
返回值为 double值为正号,大于等于 0.0 ,小于 1.0 

拓展: 其他常用的Arrays类方法:

static int binarySearch(type[] a , t y p e v)
static int binarySearch(type[] a, int start, int end , type v) 6

static void fi11(type[] a , type v)
将数组的所有数据元素值设置为 V。
参数: a 类型为 intlongshortcharbytebooleanfloatdouble 的数组。
v 与 a 数据元素类型相同的一个值。    
    
static boolean equals(type[] a, type[] b)
如果两个数组大小相同, 并且下标相同的元素都对应相等, 返回 true。
参数: a、 b 类型为 intlongshortcharbytebooleanfloatdouble 的两个数组。
  • binarySeach

    采用二分搜索算法查找值 v。如果查找成功, 则返回相应的下标值; 否则, 返回一个负数值。r -r-1 是为保持 a 有序 v 应插入的位置

    参数:

    • a 类型为 int、 long、 short、 char、 byte、 boolean 、 float 或 double 的有序数组。
    • start 起始下标(包含这个值)。
    • end 终止下标(不包含这个值。)
    • v 同 a 的数据元素类型相同的值。
发布了17 篇原创文章 · 获赞 7 · 访问量 1348

猜你喜欢

转载自blog.csdn.net/qq_42683011/article/details/104053425
今日推荐