Object类
什么是Object类?
Object类是所有类、数组、枚举类的父类,也就是说Java允许把任何类型的对象赋值给Object类型的变量。当定义一个类没有用显式extends表示继承哪个类时,默认继承Object类。
常用的方法:
- boolean equals(Object obj):判断指定对象是否与该对象相等,此处相等的标准是是同一个对象。
- protected void finalize():当系统中没有引用变量引用到该对象时,垃圾回收器调用此方法来清理该对象资源。
- Class<?>getClass():返回该对象的运行时类。
- int hashCode():返回该对象的hashCode值,默认情况下是根据地址值来计算的。但是很多类都重写了这个方法,不再根据地址来计算。
- String toString():返回带对象的字符串表示,当程序使用System.out.printIn()来输出一个对象或者对象后面连接字符串输出,系统会自动调用这个方法,返回该对象的字符串表示。但很多类都重写了这个方法,用来返回表述该对象信息的字符串。
clone()
protected修饰,该方法用于帮助其他对象来实现“自我克隆”,其实就是得到当前对象的一个副本,而且两者之间完全隔离。该方法只能被子类重写或调用。
package org.westos.demo;
class Address {
String detail;
public Address(String detail) {
this.detail=detail;
}
}
package org.westos.demo;
//实现克隆接口
public class User implements Cloneable {
int age;
Address address;
public User(int age){
this.age=age;
address=new Address("广州天河");
}
//调用super.clone方法来实现
public User clone()
throws CloneNotSupportedException
{
return (User)super.clone();
}
}
package org.westos.demo;
public class CloneTest {
public static void main(String[] args)
throws CloneNotSupportedException
{
User u1 = new User(29);
User u2=u1.clone();
System.out.println(u1==u2);
System.out.println(u1.address==u2.address);
}
}
这样克隆出来的只是一个副本,是一个浅克隆,如果对象中有一个引用类型,只克隆引用变量,而不可隆指向的实际对象。
Java7中的新增的Objects类
Java7中新增了一个Objects工具类,提供了一些工具方法来操作对象,这些工具方法大多是“空指针”安全的。
package org.westos.demo;
import java.util.Objects;
public class NewObject {
static NewObject obj;
public static void main(String[] args)
throws Exception
{
//输出一个null对象的hashCode值
System.out.println(Objects.hash(obj));
//输出一个null对象的toString,
System.out.println(Objects.toString(obj));
//要求obj不能为null,
System.out.println(Objects.requireNonNull(obj));
}
}
Scanner类
使用Scanner类可以很方便地获取用户的键盘输入,Scanner是一个基于正则表达式的文本扫描器,它可以从文件、输入流、字符串中解析出基本类型值和字符串值。Scanner类提供了多个构造器,不同的构造器可以接受文件、输入流、字符串作为数据源,用于文件、输入流、字符节中解析数据。
主要提供来两个方法来扫描输入:
- hasNextXxx():是否还有下一个输入项,其中Xxx可以是Int、Long等代表基本数据类型的字符串。如果只是判断是否包含下一个字符串,则直接使用hasNext()。
- nextXxx():获取下一个输入项。Xxx的含义与前一个方法中的Xxx相同。
package org.westos.demo;
import java.util.Scanner;
public class Scanner01 {
public static void main(String[] args) {
//System.in代表标准输入,就是键盘输入
Scanner sc = new Scanner(System.in);
sc.useDelimiter("\n");
//判断是否还有下一个输入项
while (sc.hasNext()){
//输出输入项
System.out.println("键盘输入的内容是:"+sc.next());
}
}
}
如果希望改变Scanner的分隔符,例如:程序需要每一次读取一行,不管这一行是否包含空格,Scanner都把它当成一个输入项。在这种需求下,可以把Scanner的分隔符设置为回车符,不再使用默认的空包作为分隔符。
为Scanner设置分隔符使用useDelimiter(String pattern)方法即可,该方法的参数因该是一个正则表达式,事实上,Scanner提供了两个方法来逐行读取:
- boolean hasNextLine():返回输入源中是否还有一行;
- String nextLine():返回输入源中下一行的字符串。
常用的方法
- nextInt():获取一个int类型的值;
- nextLine():获取一个String类型的值;
- next():获取一个String类型的值,
读取文件
Scanner不仅能读取用户的键盘输入,还可以读取文件输入。只要在创建Scannr对象时传入一个File对象为参数,就可以让Scanner读取文件内容。
package org.westos.demo;
import java.io.File;
import java.util.Scanner;
public class Scannerfile {
public static void main(String[] args)
//表明main函数不做任何异常处理
throws Exception
{
//将一个Files对象作为Scanner的构造器参数。
Scanner sc= new Scanner(new File("C:\\Users\\WIN10\\Desktop\\java\\day08\\20181020-JavaSE-课件\\代码\\20181020-MyJavaDemo-Scanner类-下午\\src\\org\\westos\\demo\\Scannerfile.java"));
System.out.println("文件内容如下:");
while (sc.hasNextLine()){
System.out.println(sc.nextLine());
}
}
}
System类
Java程序在不同操作系统上运行,可能需要获取平台相关的属性,或者调用平台命令来完成特定功能。Java提供了System类和Runtime类来与程序运行的平台进行交互。
System类
System类代表当前Java程序的运行平台,程序不能创建System类的对象,System类提供了一些类变量和类方法,允许直接通过System类来调用这些类变量和类方法。
System类提供了代表标准输入、标准输出和错误输出的类变量,并提供了一些静态方法用于访问环境变量、系统属性的方法,还提供了加载文件和动态链接库的方法。
访问操作的环境变量和系统属性:
package org.westos.demo;
import java.io.FileOutputStream;
import java.util.Map;
import java.util.Properties;
public class SystemTest {
public static void main(String[] args)
throws Exception
{
//获取系统所有环境变量
Map<String,String> env =System.getenv();
for (String name:env.keySet()){
System.out.println(name+"————>"+env.get(name));
}
//获取指定的环境变量的值
System.out.println(System.getenv("JAVA_HOME"));
//获取系统属性
Properties props=System.getProperties();
props.store(new FileOutputStream("props.txt"),"System Properties");
//输出特定的系统属性
System.out.println(System.getProperty("os.name"));
}
}
获取系统时间
//两个方法都返回与1970.1.1时间差
//以毫秒为单位
System.out.println(System.currentTimeMillis());
//以纳秒为单位
System.out.println(System.nanoTime());
其他方法
除此之外,System类的in、out、err分别代表标准输入,标准输出和错误输出流,并提供了setIn()、setOut、setErr()方法来改变系统的输入,输出和标准错误输入流。
还提供了一个identityHashCode(Object x)
方法,该方法单户UI制定对此昂的精确hashCode值,也就是根据对象地址计算得到的hashCode值,当某个了类的hashCode方法被重写后,该类实例的hashCode方法就不能唯一的标识对象,但通过identityHashCode(Object x)方法返回的hashCode值依然是根据该对象的地址计算得到的hashCode值。
package org.westos.demo;
public class SystemHash {
public static void main(String[] args) {
//s1和s2是两个不同的对象
String s1 = new String("hello");
String s2 = new String("hello");
//String重写了hashCode方法,改为根据字符序列计算hashCode值
//因为s1和s2的字符序列相同,所以hashCode返回的地址相同
System.out.println(s1.hashCode()==s2.hashCode());//true
//s1和s2是不同的字符串对象,所以它们的idengtityHashCode值不同
System.out.println(System.identityHashCode(s1)==System.identityHashCode(s2));//false
//s3和s4是相同的对象
String s3="java";
String s4="java";
System.out.println(System.identityHashCode(s3)==System.identityHashCode(s4));
//true
}
}
String、StringBuffer和StringBuilder类
字符串就是一连串的字符序列,Java提供了String和StringBuffer两个类来封装字符串,并提出了一系列的方法来操作字符串对象。
String类是不可变类,一旦一个Sting对象被创建后,包含着和对象中的字符序列是不可改变的,直至这个对象被销毁。
StringBuffer对象则代表一个字符序列可变的字符串,当一个stringBuffer被创建后,通过StringBuffer提供的append、insert、reverse。setCharAt、setLength等方法可以改变这个字符对象的序列,一旦通过StringBuffer转换成最终想要的字符之后,就可以调用它的toString方法来转换成一个String对象。
StringBuilder类,它也代表字符串对象。它和StringBuffer基本相似,不过它是线程安全的,而SreingBuffer不是。所以应先考虑StringBuilder类。
String提供了大量的构造器来创建String对象:
- String():包含一个创建0个字符序列的String对象,并不是返回null。
//是一个空白字符,并不是null
String s1=new String();
System.out.println(s1);
- String(byte[] bytes):把字节数组转换成字符串。
byte[] by={98,99,100,101};
String s2 = new String(by);
System.out.println(s2);//bcde
- String(byte[],int offset,int length):把一部分转换成字符串。
byte[] by1={98,99,100,101};
String s3=new String (by,1,3);
System.out.println(s3);
- String(char[] value):把字符数组转换成字符串。
char[] chs1={'a','b',100,'e'};
String s5 = new String(chs,1,3);
System.out.println(s5);//bde
- String(char[] value,int offset,int count):将指定的字符数组从offset开始,长度为count的字符原连缀成字符串。
char[] chs1={'a','b',100,'e'};
String s5 = new String(chs,1,3);
System.out.println(s5);//bde
- String(String original):把字符常量转换成字符串。
String s = new String("abc");
-
String(StingBuffer buffer):根据StingBuffer对象来创建对应的String对象;
-
String(StingBuilder builder):根据StingBuilder对象来创建对应的String对象;
String类也提供了大量的方法来操作字符串对象
- charAt(int index):获取index指定位置的字符。
String s=new String("helloworldandjava");
System.out.println(s.charAt(5));//w
for (int i=0;i<s.length();i++){
if(i%2==0){
System.out.print(s.charAt(i));//hlooladaa
}
}
- int compareTo(String anotherString):比较两个字符串大小。如果两个字符串相等则返回0,从第0个字符开始比较,返回第一个不相等的字符差。比较较长字符串前面部分恰巧是较短字符串,则返回他们的长度差。
String s1=new String("abcde");
String s2=new String("abcde");
String s3=new String("abbde");
String s4=new String("abb");
System.out.println(s2.compareTo(s1));//0 相等返回0
System.out.println(s2.compareTo(s3));//1 返回不相等字符的差值
System.out.println(s3.compareTo(s4));//2 返回长度差
- String concat(String str):将该String对象与str连接在一起,与’+'功能相同。
String s = new String("hello");
System.out.println(s.concat("world"));//helloworld
- boolean contentEquals(StringBuffer sb):如果包含的字符序列相同的话返回true;
String s = new String("hello");
StringBuffer sB = new StringBuffer("hello");
System.out.println(s.contentEquals(sB));//true
- static String copyValueOf(char[] data,int offset,int count):将char数组的子数组中的元素连缀成字符串。
- static String copyValueOf(char[] data):将char数组中的元素连缀成字符串
char[] ch={97,'b',65,100,'h',67};
System.out.println(String.copyValueOf(ch));//abAdhC
System.out.println(String.copyValueOf(ch,3,2));//dh
- boolean endsWith(String suffix):返回该String对象是否以suffix结尾。
String s = new String("hello");
System.out.println(s.endsWith("lo"));//true
- boolean equals(Object anObject):将该字符串与指定字符串对象比较,如果序列相同则返回true。
- boolean equalsIgnoreCase(String str):与前一个方法相同,只是忽略了大小写。
- byte[] getBytes():将String对象转换为byte数组。
String s = new String("hello world 123");
for (int i=0;i<s.getBytes().length;i++){
System.out.print(s.getBytes()[i]+",");
}
//104,101,108,108,111,32,119,111,114,108,100,32,49,50,51,
- void getChars(int scrBegin,int srcEnd,char[] dst,int dstBegin):该方法将字符串中从srcBegin开始,到srcEnd结尾的字符复制到dst字符数组中。其中dstbegin为目标数组的起始复制位置。
String s = new String("hello world");
char[] c={'i',' ','l','o','v','e','j','a','v','a'};
s.getChars(0,3,c,3);
System.out.println(c);
- int indexOf(int ch):找出ch字符在字符串中第一次出现的位置;
- int indexOf(int ch,int fromIndex):找出ch字符在该字符串转中从fromIndex开始后第一次出现的位置。
- int indexOf(String str):找出str子字符串在该字符串中第一次出现的位置;
- int indexOf(String str,int fromIndex):找出str子字符串在该字符串中从fromIndex开始后第一次出现的位置。
String s = new String("hello world 1,23");
System.out.println(s.indexOf("r"));//8
System.out.println(s.indexOf("r",4));//8
System.out.println(s.indexOf("wor"));//6
System.out.println(s.indexOf("wor",1));//6
- String replace(char oldChar,char newChar):将字符串中的第一个oldChar替换成newChar。
String s = new String("hello world 1,23");
System.out.println(s.replace("l","o"));//heooo worod 1,23
- int laseIndexOf(int ch):找出ch字符在该字符串中最后一次出现的位置;
- int laseIndexOf(int ch,int fromIndex):找出ch字符在该字符串中从fromIndex开始最后一次出现的位置;
-
- int laseIndexOf(String str):找出str子字符字符串在该字符串中最后一次出现的位置;
- int laseIndexOf(String str,int fromIndex):找出str子字符字符串在该字符串中从fromIndex开始最后一次出现的位置;
String s = new String("hello world 1,23");
System.out.println(s.lastIndexOf("l"));//9
System.out.println(s.indexOf("l"));//2
System.out.println(s.lastIndexOf("l",8));//3
System.out.println(s.lastIndexOf("lo"));//3
System.out.println(s.lastIndexOf("lo",5));//3
- int length():返回该字符串长度;
- boolean startsWith(String prefix):该对象是否以prefix开头;
-
- -boolean startsWith(String prefix,int toffset):该对象是否从toffset开始以prefix开头;
- boolean endsWith(String prefix):该对象是否以prefix结尾;
String s = new String("hello world 1,23");
System.out.println(s.endsWith("23"));//true
System.out.println(s.startsWith("he"));// true
System.out.println(s.startsWith("wo",5));//false
- String substring(int beginIndex):获取从beginIndex位置开始到结束位置的子字符串;
- String substring(int beginIndex,int endIndex):获取从beginIndex位置开始到endIndex结束位置的子字符串;
String s = new String("I Love Java");
System.out.println(s.substring(4));//ve Java
System.out.println(s.substring(4,6));//ve
- char[] toCharArray():将该String对象转换成char数组;
- String toLowerCase():将字符串转换成小写;
- String toUpperCase():将字符串转换成大写;
System.out.println(s.toCharArray());//I Love Java
System.out.println(s.toLowerCase());//i love java
System.out.println(s.toUpperCase());//I LOVE JAVA
- static String valueOf(X x):一系列将基本类型转换成String对象的方法。
String类的特性
字符串是常量创建之后不能再更改;
两种定义方式的比较
//两种定义字符串方式的区别
String s = new String("hello");
String s2 = "hello";
String s3="hello";
System.out.println(s2==s3);//true
System.out.println(s==s2);//false
两种方式的区别:第一种方式是在栈内存中创建一个对象,检查常量池中是否有没有这个常量,不管有没有都再创建一个对象在常量池中。
第二种方法是直接赋值,在常量池中储存这个常量,在一个如果有同样的常量要定义,就先在常量池中检查如果存在就直接指向已有的这个常量,否则就再在常量池中创建一个。
数学工具类Math
Math是一个工具类,用于完成像三角函数、对数运算等这样的复杂数学运算。这个类的构造器被private修饰,因此无法创建对象,其中的所有方法都是类方法,可以直接通过类名来调用它们。除此之外它还提供了两个类变量,PI表示圆周率,E相当于e。
实例:
列出了常用的几个方法:
package org.westos.Mathdemo;
public class Mathclass {
public static void main(String[] args) {
//将弧度转换为角度
System.out.println(Math.toDegrees(1.57));//89.95437383553926
//将角度转换为弧度
System.out.println(Math.toRadians(90));//1.5707963267948966
//计算余弦,角度0到PI之间
System.out.println(Math.cos(1.57));//7.963267107332633E-4
//计算反余弦
System.out.println(Math.acos(1.2));//NaN
//向上取整,返回比目标数大的最大整数
System.out.println(Math.floor(-1.345));//-2.0
//向下取整
System.out.println(Math.ceil(-1.345));//-1.0
//取目标数的绝对值
System.out.println(Math.abs(-3));//3
System.out.println(Math.abs(5));//5
//计算平方根
System.out.println(Math.sqrt(2.3));//1.51657508881031
//计算立方根
System.out.println(Math.cbrt(8));//2.0
//计算乘方
System.out.println(Math.pow(3,2));//9.0
//计算对数
System.out.println(Math.log(16));//2.772588722239781
System.out.println(Math.log10(100));//2.0 计算以10为底的对数
//找出最大值
System.out.println(Math.max(43,76));//76
//找出最小值
System.out.println(Math.min(-34,23));//-34
//返回0~1之间随机数
System.out.println(Math.random());//0.02395063406412057
}
}
随机类ThreadLocalRandom和Random
Random
专门用于生成一个伪随机数,它有两个构造器:一个构造器使用默认的种子,另一个构造器需要程序员显式传入一个long型整数种子。
TreadLocalRandom
与Random用法基本类似,它提供了一个静态的current方法来获取TreadLocalRandom对象,获取该对象之后即可调用各种nextXxx()方法来获取伪随机数了。
实例:
Random rand = new Random();
//随机布尔型
System.out.println(rand.nextBoolean());
//生成一个随机字节型数组
byte[] buffer = new byte[16];
rand.nextBytes(buffer);
System.out.println(Arrays.toString(buffer));
//生成0.0~1.0之间的伪随机double数
System.out.println(rand.nextDouble());
//生成0.0~1.0之间的伪随机float数
System.out.println(rand.nextFloat());
//生成一个处于long整数取值范围的伪随机数
System.out.println(rand.nextLong());
//生成一个处于int整数取值范围的伪随机数
System.out.println(rand.nextInt());
//生成一个处于给定范围的int数
System.out.println(rand.nextInt(26));
种子
Random使用一个48位的种子,如果这个类的两个实例使用同一个种子创建的,对于它们以相同的顺序调用方法,则它们会产生相同的数字序列。
//种子为50的对象
Random r1=new Random(50);
System.out.println(r1.nextInt());
System.out.println(r1.nextDouble());
//-1160871061
//0.5978920402252371
Random r2 = new Random(50);
System.out.println(r2.nextInt());
System.out.println(r2.nextDouble());
//-1160871061
//0.5978920402252371
Random r3 = new Random(100);
System.out.println(r3.nextInt());
System.out.println(r3.nextDouble());
// -1193959466
// 0.7346627443280227
只要两个对象的种子相同,并且调用方法的顺序相同,就可以产生相同的数字序列。所以Random并不是真正的随机,只是一种伪随机。
为了避免产生相同的数字序列,一般以当前时间作为Random对象的种子
Random rand = new Random(System.currentTimeMillis());
BigDecimal类
在很多语言中,float、double类型在数学运算时容易引起精度丢失。所以Java提供了BigDecimal类,该类提供了大量构造器用于创建BigDecimal对象,包括把基本类型变量转换成一个BigDecimal对象,也包括利用数字字符串和数字字符数组来创建对象。
BigDecomal(double val)构造器有一定的不预知性,当使用这个构造器创建对象时,它得到的值接近于目标值.
BigDecimal bg1 = new BigDecimal(0.1);
System.out.println(bg1);
//0.1000000000000000055511151231257827021181583404541015625
这是因为0.1无法准确表示为double浮点数。
如果必须使用double浮点数作为此类构造器的参数,应该通过BigDecimal.valueOf(double value)静态方法来创建对象。
BigDecimal f1 = new BigDecimal("0.05");
BigDecimal f2 = BigDecimal.valueOf(0.01);
BigDecimal f3 = new BigDecimal(0.05);
//使用String作为构造器参数
System.out.println(f1.add(f2));//0.06
System.out.println(f1.subtract(f2));//0.04
System.out.println(f1.multiply(f2));//0.0005
System.out.println(f1.divide(f2));//5
//使用double作为构造器参数
System.out.println(f3.add(f2));//0.06
System.out.println(f3.subtract(f2));//0.04
System.out.println(f3.multiply(f2));//0.0005
System.out.println(f3.divide(f2));//5
/*0.06000000000000000277555756156289135105907917022705078125
0.04000000000000000277555756156289135105907917022705078125
0.0005000000000000000277555756156289135105907917022705078125
5.000000000000000277555756156289135105907917022705078125*/