文章目录
1.System类
java.lang.System类提供了大量的静态方法,可以获取系统相关的信息或执行系统操作,常用方法有:
-
static long currentTimeMillis(): 返回以毫秒为单位的当前时间
-
static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length): 将数组中指定的数据拷贝到另一个数组中
- src:源数组
- srcPos:源数组的起始位置
- dest:目标数组
- destPos:目标数组的起始位置
- length:要复制的内容的长度
import java.util.Arrays;
public class SystemMain {
public static void main(String[] args) {
long time = System.currentTimeMillis();
System.out.println(time); // 1587609427487
int[] src = new int[]{1,2,3,4};
int[] dest = new int[]{5,6,7,8};
System.arraycopy(src, 0, dest, 0, 3);
System.out.println(Arrays.toString(dest)); // [1, 2, 3, 8]
}
}
2.StringBuilder类
Java中的字符串的底层实现为一个被final关键字修饰的字节数组,因此,一旦创建就不能改变。如果直接使用+进行字符串的拼接,那么内存会保存拼接的中间结果,这样的方法会占用较多的内存,效率低下。
StringBuilder是字符串缓冲区,它可以提高字符串的操作效率,它的底层实现也是一个数组,但是并没有被final关键字修饰,因此可以改变长度。StringBuilder在内存中始终是一个数组,占用空间少,效率高,如果超出了StringBuilder的容量会自动进行扩容。
-
构造方法:
- StringBuilder() :构造一个不带任何字符串的字符串生成器,其实容量为16个字符
- StringBuilder(String str) :构造一个字符串生成器,并初始化为指定的字符串内容
public class StringBuilderMain { public static void main(String[] args) { StringBuilder sb = new StringBuilder(); System.out.println(sb); // "" StringBuilder sb1 = new StringBuilder("Forlogen"); System.out.println(sb1); // Forlgoen } } -
StringBuilder append(…) :添加任意类型数据的字符串形式,并返回当前对象自身
public class StringBuilderMain { public static void main(String[] args) { StringBuilder sb = new StringBuilder(); System.out.println(sb); // "" sb.append("Forlogen"); sb.append(24); System.out.println(sb); // Forlogenkobe24 } } -
StringBuilder和String之间的相互转换:
- StringBuilder -> String:使用StringBuilder的toString方法
- String -> StringBuilder:使用上述的构造方法
public class StringBuilderMain { public static void main(String[] args) { StringBuilder sb = new StringBuilder("Forlogen"); System.out.println(sb); // Forlgoen System.out.println(sb.toString()); // Forlogen } } -
int length() :获取字符串的长度
-
StringBuilder insert() :将内容插入到StringBuilder对象的指定位置
public class StringBuilderMain { public static void main(String[] args) { StringBuilder sb = new StringBuilder("Forlogen"); System.out.println(sb.length()); // 8 System.out.println(sb.insert(3, "KOBE")); // ForKOBElogen } }
3.Object类
java.lang.Object类所有类的根类,每个类都将Object作为超类,所有类的对象,包括数组都实现这个类的方法。常用的方法:
-
String toString() :返回对象的字符串表示。假设Person定义如下所示,它默认继承了Object这个超类:
public class Person { private String name; private int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }如果我们直接通过对象调用toString方法,最后得到的对象的地址值,本质上和直接输出对象自己没有区别。
public class ObjectMain { public static void main(String[] args) { Person person = new Person("Forlogen", 18); System.out.println(person); // Object.Person@1b6d3586 // 直接打印对象的名字本质上就是调用了对象的toString方法 String s = person.toString(); System.out.println(s); // Object.Person@1b6d3586所以,为了更加使toString符合具体的应用场景,我们需要重写toString方法,在IDEA中使用自动生成得到:
@Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; }如上所示,通过重写方法最后得到的是类的成员变量信息而不是对象的地址值。那么,我们再看一些Java内置的其他类是否也重写了toString方法:
Random r = new Random(); System.out.println(r); // java.util.Random@74a14482从输出结果可以看出,Random并没有重写toString方法。
// 重写了toString Scanner sc = new Scanner(System.in); System.out.println(sc); // java.util.Scanner[delimiters=\p{javaWhitespace}+][position=0] ...从输出结果可以看出,Scanner类重写了toString方法,我们通过源码看一下具体的重写过程:
/** * <p>Returns the string representation of this <code>Scanner</code>. The * string representation of a <code>Scanner</code> contains information * that may be useful for debugging. The exact format is unspecified. * * @return The string representation of this scanner */ public String toString() { StringBuilder sb = new StringBuilder(); sb.append("java.util.Scanner"); sb.append("[delimiters=" + delimPattern + "]"); sb.append("[position=" + position + "]"); sb.append("[match valid=" + matchValid + "]"); sb.append("[need input=" + needInput + "]"); sb.append("[source closed=" + sourceClosed + "]"); sb.append("[skipped=" + skipped + "]"); sb.append("[group separator=" + groupSeparator + "]"); sb.append("[decimal separator=" + decimalSeparator + "]"); sb.append("[positive prefix=" + positivePrefix + "]"); sb.append("[negative prefix=" + negativePrefix + "]"); sb.append("[positive suffix=" + positiveSuffix + "]"); sb.append("[negative suffix=" + negativeSuffix + "]"); sb.append("[NaN string=" + nanString + "]"); sb.append("[infinity string=" + infinityString + "]"); return sb.toString(); }重写过程中使用了StringBuilder来保存输出的结果,最后使用StringBuilder中的toString方法输出字符串。
ArrayList<String> list = new ArrayList<>(); list.add("Forlogen"); list.add("kobe"); System.out.println(list); // [Forlogen, kobe]可以看到ArrayList也重写了toString方法,但是在ArrayList的实现中并没有自己重写toString,而ArrayList继承了java.util包下的AbstractCollention<E>类,该类中进行了toString方法的重写。
/** * Returns a string representation of this collection. The string * representation consists of a list of the collection's elements in the * order they are returned by its iterator, enclosed in square brackets * (<tt>"[]"</tt>). Adjacent elements are separated by the characters * <tt>", "</tt> (comma and space). Elements are converted to strings as * by {@link String#valueOf(Object)}. * * @return a string representation of this collection */ public String toString() { Iterator<E> it = iterator(); if (! it.hasNext()) return "[]"; StringBuilder sb = new StringBuilder(); sb.append('['); for (;;) { E e = it.next(); sb.append(e == this ? "(this Collection)" : e); if (! it.hasNext()) return sb.append(']').toString(); sb.append(',').append(' '); } }重写的过程和Scanner是类似的。
-
boolean equals(Object obj): 指示其他某个对象是否和此对象相等,Object类中的equals方法实现代码为:
public boolean equals(Object obj) { return (this == obj); }它实现了本身和传入的对象的对比。我们知道 == 对于引用类型来说,进行的是地址值的比较,所以如果不是两个完全相同的对象,那么得到的就是false。
public class ObjectEquals { public static void main(String[] args) { Person person = new Person("Forlogen", 18); Person person1 = new Person("kobe", 24); System.out.println(person.equals(person1)); // false } }同样为了具体的应用场景,通常需要重写equals方法:
@Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Person)) return false; Person person = (Person) o; return getAge() == person.getAge() && Objects.equals(getName(), person.getName()); } @Override public int hashCode() { return Objects.hash(getName(), getAge()); }Java内置的其它类中很多也重写了equals方法,如String中就进行了equals方法:
/** * Compares this string to the specified object. The result is {@code * true} if and only if the argument is not {@code null} and is a {@code * String} object that represents the same sequence of characters as this * object. * * @param anObject * The object to compare this {@code String} against * * @return {@code true} if the given object represents a {@code String} * equivalent to this string, {@code false} otherwise * * @see #compareTo(String) * @see #equalsIgnoreCase(String) */ public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }通过对象直接调用
public class ObjectEquals { public static void main(String[] args) { String s1 = "abc"; String s2 = "abc"; System.out.println(s1.equals(s2)); // true } }通常为了避免使用equals方法出现空指针异常,可以使用Objects的equals方法:
public class ObjectEquals { public static void main(String[] args) { String s1 = null; String s2 = "abc"; System.out.println(s1.equals(s2)); // 会出现空指针异常 System.out.println(Objects.equals(s1, s2)); // false } }