新人创作,不足之处还望大家多多指点~~
本文如有侵权,练习作者马上删!
来源:java. lang. Object
Object类是所有类的父类,类似于"万物之首",包括我们自己写的类,其父类都是Object类,如果一个类没有特别指定父类,那么它默认继承自Object类。
protected Object clone()
public boolean equals(Object obj)
protected void finalize()
public int hashCode()
public final class getClass()
public String toString()
返回的是类的全路径名+hash值; 但在实际开发中,我们一般会重写掉toString()方法,不会使用Object的toString(),因为其没有什么意义…
方法toString()重写如下:
public class Person{
//Person类默认继承(extends)Object类
//成员变量:定义在类中且方法外的变量
private String name;
private int age;
@Override
public String toString() {
//重写的toString()方法
return "Person{" + "name='" + name + '\'' + ", age=" + age + '}';
}
}
比较两个对象是否相等,默认是地址与地址之间的比较; 如果没有覆盖重写equals方法,那么Object类中只要不是同一个对象,比较结果必然为false。
若希望进行对象内容之间的一个比较,则必须重写该方法,以实现对象之间进行内容的比较
注意:若对象为null,调用其equals()方法时,会抛NullPointException异常,下面的Objects中的equals方法解决了该问题.
方法重写代码如下:
import java.util.Objects;
public class Person {
private String name;
private int age;
//有参构造函数
public Person(String name,int age){
this.name = name;
this.age = age;
}
@Override // Person类重写了Object类中的equals()方法
public boolean equals(Object obj) {
// 如果对象地址一样,则认为相同
if (this == obj)
return true;
// 如果参数obj为空,或者类型(类)信息不一样,则认为不同对象,直接返回false
if (obj == null || getClass() != obj.getClass())
return false;
Person person = (Person) obj; // 转换为当前类型
// 要求基本类型相等,并且将引用类型交给java.util.Objects类的equals静态方法判断结果
return age == person.age && Objects.equals(name, person.name);
}
}
在上面重写equals()方法时,相信大家已经看到了一个Objects类的引用,那么这个类是什么呢?
来源:java.util.Objects
在JDK7后添加了一个Objects工具类,它提供了一些方法来操作对象,它由一些静态的实用方法组成,这些方法是null-save(空指针安全的)或null-tolerant(容忍空指针的),用于计算对象的hashcode、返回对象的字符串表示形式(toString)、比较两个对象(equals)等。
上面已经说了在比较两个对象的时候,Object的equals方法容易抛出空指针异常(当对象为null时),而Objects类中的equals方法就优化了这个问题。方法如下:
public static boolean equals(Object obj,Object obj)
判断两个对象是否相等(比较内容而非地址)
源码如下:
可以看到它底层的源码也调用了Object.equals()
方法,并且进行了a是否为null的一个判断,如果为null的话,后面的a.equals(b)
必然是不会调用的,所以巧妙地避免了NullPointException异常
除了上面列出的日常开发中使用的最多的equals()方法外,还存在一些其他方法
来源: java.lang.String
Java程序中所有双引号(" ")内的字符都属于字符串(String),字符串创建后其值存在于JVM的方法区内存当中,并且其定义的值在创建后就不能被改变
String s1 = "abc";
s1 += "d";
System.out.println(s1); // "abcd"
// 方法区内存中有"abc","abcd"两个字符串对象,s1从指向"abc",改变指向,指向了"abcd"
正因为String类型的数据一旦定义就不能修改,所以如果你创建一个前面已经被创建过的字符串,后创建的字符串会先在方法区内存的字符串常量池(实例池)中寻找该字符串,若不存在则自己创建一个,如果存在就指向那个已存在的值,所以他们的值是可以被共享的。
String s1 = "abc"; //"abc"在方法区内存的常量池中被定义, s1指向该字符串"abc"
String s2 = "abc"; //s2先在常量池中寻找字符"abc",存在则直接指向它,不存在则自己定义一个,并且指向它
// 总结:内存中只有一个"abc"对象被创建,同时被s1和s2共享。
字符串 “abc” 等效于 char[] strs = { ‘a’ , ‘b’ , ‘c’ } ;
String str = “” 等效于 String str = new String( );
//例如:
String str = "abc";
//相当于:
char data[] = {'a', 'b', 'c'};
String str = new String(data); // String底层是靠字符数组实现的
方法名 | 说明 |
---|---|
new String( ) | 创建一个空白字符串对象,不含任何内容 |
new String(char[] chs) | 根据字符数组的内容,来创建字符串对象 |
new String(byte[] bys) | 根据字节数组的内容,来创建字符串对象 |
String s = “abc” | 直接赋值的方式创建字符串对象,内容就是abc |
来源: java.lang.Object
StringBuilder 是一个可变的字符串类,我们可以把它看成是一个容器,这里的可变指的是 StringBuilder 对象中的内容是可变的,因为其底层数组没有采用final
关键字修饰,所以该数组是可变的,而String类底层的数组被final
修饰,所以一旦创建就不可更改,这就是二者之间的最大区别~
构造方法名 | 说明 |
---|---|
new StringBuffer() | 构造一个没有字符的字符串缓冲区,初始容量为16个字符。 |
new StringBuffer(CharSequence seq) | 构造一个含有指定seq内容的字符串缓冲区,初始容量为16+seq的长度 |
new StringBuffer(int capacity) | 构造一个没有字符的字符串的缓冲区并指定其初始容量 |
new StringBuffer(String str) | 构造一个初始化为指定字符串内容str的字符串缓冲区 |
注意:以下StringBuffer类中所有涉及到下标的方法,其下标都从0开始,并且区间范围都属于半闭半开[begin,end )
append()
insert()
charAt(int index)
codePointAt(int index)
delete(int begin, int end)
deleteCharAt(int index)
indexOf(String str)
indexOf(String str, int index)
replace( int begin, int end, String str)
reverse()
setCharAt(int index, char ch)
将指定索引处的字符用ch代替,若index下标超过字符串缓冲区总长度,则会抛出字符串索引越界异常"StringIndexOutOfBoundsException"
代码如下:
package com.obtk.day18;
public class Demo01 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("abced");
//当前总长度为5,不存在下标为7的元素
sb.setCharAt(7,'p');
System.out.println(sb);
}
}
执行结果如下:
注:总长度length为5,下标index为7,所以会抛异常错误!!
可以借助StringBuffer类的toString( )方法将StringBuffer转换为String类型
可通过StringBuffer的构造方法将String类型转换为StringBuffer类型
例如 :new StringBuffer(String str);
具体实现代码如下:
public class StringBufferDemo02 {
public static void main(String[] args) {
//StringBuffer 转换为 String
StringBuffer sb = new StringBuffer();
sb.append("hello"); //添加"hello"到字符串缓冲区
String s = sb; //这个是错误的做法
//public String toString()
//通过 toString()就可以实现把 StringBuffer转换为String
String s = sb.toString();
System.out.println(s);
// String 转换为 StringBuffer
String s = "hello";
//StringBuilder sb = s; //这个是错误的做法
//通过构造方法就可以实现把 String 转换为 StringBuffer
StringBuffer sb = new StringBuffer(s);
System.out.println(sb); // 输出hello
}
}
来源: java.util.Date
在日常生活中,有一个东西一直伴随着我们,那就是时间。java作为一门热门的高级语言,自然也为我们提供了一些对时间进行操作的类,例如Date,DateFormat,SimpleDateFormat,现在,我们就从以上三个类开始,对日期时间类进行一些简单的介绍
通过查阅API文档,我们发现Date拥有多个构造函数,只是部分已经过时,但是其中有未过时的构造函数可以把毫秒值转成日期对象。常用的两种构造方法如下:
new Date()
: 分配一个Date对象并初始化此对象,以便它表示分配的时间(精确到最近毫秒)
new Date(long date)
:分配Date对象并初始化此对象,以表示从标准基准时间(称为“历元(epoch)",即1970年1月1日00:00:00 GMT)以来的指定毫秒数。
public class Demo03 {
public static void main(String[] args) {
//获取1970-1-1 0:0:0 到其1000毫秒之后的时间
Date date = new Date(1000);
//(注:由于我们处于东八区,所以我们的基准时间为1970年1月1日8时0分0秒。)
//输出1970-1-1 8:0:01
System.out.println(date);
}
}
Date类中的多数方法已经过时,留存下来算常用的还有如下几种:
java.text.DateFormat 是日期/时间格式化子类的抽象类,我们通过这个类可以帮我们完成日期和文本之间的转换,也就是可以在Date对象与String对象之间进行来回转换,将其转换成我们所了解的形式。
由于DateFormat为抽象类,不能直接使用,所以需要常用的子类public SimpleDateFormat(String pattern)
这个类来进行实例化,
注: 参数pattern是一个字符串,代表日期时间的自定义格式
一般格式如下:
//实例化日期/时间格式化对象SimpleDateFormat,并自定义其转换格式
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
常用格式规则如下
标识字母(区分大小写) | 含义 |
---|---|
y | 年 |
M | 月 |
d | 日 |
H | 小时 |
m | 分钟 |
s | 秒 |
备注:更详细的格式规则,可以参考SimpleDateFormat类的API文档
DateFormat类的常用方法有
使用format方法的代码如下:
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
/*把Date对象转换成String*/
public class Demo04DateFormatMethod {
public static void main(String[] args) {
Date date = new Date(); //获取日期
// 创建日期格式化对象,在获取格式化对象时可以指定风格
DateFormat df = new SimpleDateFormat("yyyy年MM月dd日");
//将date对象按照"yyyy年MM月dd日"的格式转换为字符串
String str = df.format(date);
System.out.println(str); // 2008年1月23日
}
}
使用parse方法的代码如下:
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/* 把String转换成Date对象*/
public class Demo05DateFormatMethod {
public static void main(String[] args) throws ParseException {
/*注意:字符串年月日的格式必须和df后面指定的格式一致,否则无法正确转换*/
//设定df时间对象的日期格式
DateFormat df = new SimpleDateFormat("yyyy年MM月dd日");
String str = "2018年12月11日";
//将字符串str转换为Date类型的日期格式
Date date = df.parse(str);
System.out.println(date); // Tue Dec 11 00:00:00 CST 2018
}
}
来源:java.util.Calendar
java.util.Calendar是日历类,在Date类后出现,替换掉了许多Date的方法。该类将所有可能用到的时间信息封装为静态成员变量,方便获取。日历类就是方便获取各个时间属性的一个工具类。
因为Calendar为抽象类,所以由于语言敏感性,Calendar类在创建对象时并非直接创建,而是通过静态方法public static Calendar getInstance()
创建,返回子类对象,如下
import java.util.Calendar;
public class Demo06CalendarInit {
public static void main(String[] args) {
//调用Calendar的静态方法创建对象,使用默认时区和语言获得一个日历
Calendar cal = Calendar.getInstance();
}
}
Calendar提供了很多成员变量,代表给定的日历字段
字段值 | 含义 |
---|---|
YEAR | 年 |
MONTH | 月(从0开始) |
DAY_OF_MONTH | 一个月中的第几天 |
HOUR | 小时(12小时制) |
HOUR_OF_DAY | 小时(24小时制) |
MINUTE | 分 |
SECOND | 秒 |
DAY_OF_WEEK | 一周中的某一天 |
注:西方星期的开始为周日,中国为周一。在Calendar类中,月份的表示是以0-11代表1-12月。日期是有大小关系的,时间靠后,时间越大。
package com.obtk.day20;
//导入外部工具包
import java.time.Year;
import java.util.Calendar;
public class Demo02 {
public static void main(String[] args) {
//实例化日历对象
Calendar c1 = Calendar.getInstance();
System.out.println(c1.getTime());
System.out.println(c1.get(Calendar.DAY_OF_MONTH)); //获取当月天数
System.out.println(c1.get(Calendar.YEAR));//获取年份
c1.set(Calendar.YEAR,1995); //设置年份为1995
System.out.println(c1.get(Calendar.YEAR));
c1.add(Calendar.YEAR,-3); //当前年份减去3,得到新年份1992
System.out.println(c1.get(Calendar.YEAR));
System.out.println(c1.get(Calendar.DAY_OF_WEEK)); // 返回 周几
}
}
java.lang.System类中提供了大量的静态方法,可以获取与系统相关的信息或系统级操作,在System类的API文档中,常用的方法有:
public static long currentTimeMillis()
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
static Properties getProperties()
static String getProperties()
static long gc()
static void exit(int status)
代码演示如下:
package com.obtk.day20;
import java.util.Arrays;
//数组拷贝System.arraycopy()方法演示
public class Demo03 {
public static void main(String[] args) {
int[] arr1 = new int[]{1,2,3,4,5};
int[] arr2 = new int[]{6,7,8,9,10};
//代表从arr1的索引0处复制元素到arr2中索引为2处,并且复制三个元素
System.arraycopy(arr1,0,arr2,2,3);
System.out.println(Arrays.toString(arr2));//运行结果: [6,7,1,2,3]
}
}
用于表示虚拟机运行时的状态,里面封装JVM虚拟机运行。每次使用java命令启动虚拟机都对应一个Runtime实例。并且只有一个实例;该类采用单例模式进行设计。
单例模式:保证整个系统中一个类只有一个对象的实例,实现这种功能的方式就叫单例模式
了解:单例模式的好处:
1. 节省公共资源
2. 方便控制
测试自己的电脑是多少核的代码:
public class Demo03Runtime {
public static void main(String[] args) {
//获得一个Runtime的实例
Runtime rt = Runtime.getRuntime();
System.out.println("处理器的个数:"+rt.availableProcessors()+"个");
//默认单位字节
System.out.println("空闲内存数"+rt.freeMemory()/1024/1024+"M");
System.out.println("最大可用内存数"+rt.maxMemory()/1024/1024+"M");
}
}
通过代码打开系统中的应用程序:采用Runtime类的exec( )方法; 代码如下:
public class Demo04Runtime2 {
public static void main(String[] args) throws IOException, InterruptedException {
//创建Runtime实例对象
Runtime runtime = Runtime.getRuntime();
//打开记事本 等于产生一个新的进程
Process process = runtime.exec("notepad.exe");
//程序休眠3秒 3秒后继续执行下面的程序
Thread.sleep(3000);
//杀掉(关闭)进程
process.destroy();
}
}
常用查找算法:
代码演示如下:
package com.obtk.day20;
import java.util.Arrays;
/*1.二分查找法*/
public class Demo04 {
public static void main(String[] args) {
int[] arr = new int[]{98,78,45,12,45,11,55};
//二分查找法的前提条件就是元素处于升序状态
Arrays.sort(arr);
System.out.println(myBinarySearch(arr,11));
}
public static int myBinarySearch(int[] arr,int num){
int left = 0; //获取起始下标
int right = arr.length-1; //获取最后一个元素下标
while(left <= right){ //left小于right,代表所有区间始终大于等于1
int mid = (left+right)/2; //获取区间中间值
//判断中间值是否是我们要找的nunm
if (arr[mid] == num){
return mid; //若是则直接返回其下标
}else if(arr[mid] > num){
//num元素小于中间值,表示mid右边所有值都比num大,所以右边的值都不需要比较,缩短右边区间到mid-1处
right = mid-1;
}else if(arr[mid] < num){
//num大于中间值,即大于所有中间值mid左边的值,那么左边的值也无需比较,直接缩短左边区间到mid+1处
left = mid + 1;
}
}
return -1;
}
}
代码演示如下:
package com.obtk.day20;
import java.util.Arrays;
/*2.暴力搜索法:找出有序数列中指定元素的索引*/
public class Demo05 {
public static void main(String[] args) {
int[] arr = new int[]{98,78,45,12,45,11,55};
Arrays.sort(arr); //搜索前对元素进行排序
System.out.println(Search(arr,11));
}
public static int Search(int arr[],int num){
for (int i = 0; i < arr.length; i++) {
if (arr[i] == num){ //通过循环一个一个比较
return i;
}
}
//找不到元素就返回-1
return -1;
}
}
作者:胡亦
时间:2021年11月29日22:06:43
创作不易,希望大家多多点赞支持以下~~