重学Java之核心类

重学Java核心类

一、String

Java字符串的特点:

  • 字符串对象可以直接使用"..."表示
  • 内容不可变
  • 使用equals()判断是否相等

字符串常用操作:

  • 是否包含子串
    • int contains
    • int indexOf/lastIndexOf
    • boolean startsWith/endsWith
  • 去除首尾空白字符
    • trim()
    • 移除首尾空白字符
    • 空格、\t、\r、\n
    • 不改变字符串,返回新字符串
  • 提取子串:substring
  • 大小写转换:
    • toUpperCase/toLowerCase
  • 替换子串:
    • replace/replaceAll
  • 分割:split
  • 拼接:join
  • 任意类型数据转换为String
    • static String valueOf()
    • String.valueOf(true) //"true"
  • 把String转换为其他类型
    • static int Integer.parseInt(String)
    • static Integer Integer.valueOf(String)
  • String转换为char[]
    • char[] toCharArray()
  • char[]转换为String
    • new String(char[])
  • String转换为byte[]
    • byte[] getBytes() 不推荐
    • byte[] getBytes(String)
    • byte[] getBytes(Charset)
  • byte[]转换为String
    • new String(byte[], String)
    • new String(byte[], Charset)

编码

最早的字符编码是ASCII码,一个字符占一个字节,最多表示128个字符。字符'A'的编码是0x41

中文编码:GB2132,GBK,GB 18030。一个中文字符占2个字节,第一个字节最高位是1。其它语言编码:Shift_ JIS, Euc-kr , ......

全球统一编码: Unicode。全球所有文字都有唯一编码。一个Unicode字符通常占2个字节。Java使用Unicode编码。

有了Unicode为什么还需要UTF-8? 英文Unicode编码和ASCII不一致,同时包含大量英文的文本会浪费空间。

UTF-8编码是变长编码 - 英文UTF-8编码和ASCII一致 - 其它Unicode字符需2~6字节不等 - UTF-8编码容错能力强:

OxXXXXxx 11 OxxxXX 10xXXXXX 111 OxXxx 10xXXxXx 10xXXXXX

编码最佳实践

  • Java使用Unicode编码
  • Java程序运行时使用Unicode编码
  • 输入输出时把String和byte[]转换,需要考虑编码
  • 始终优先考虑UTF-8编码

总结

  • 字符串是不可变对象
  • 字符串操作不改变原字符串内容,而是返回新字符串
  • 常用的字符串操作:提取子串、查找、替换、大小写转换等
  • 字符串和byte[]互相转换时要注意编码,建议总是使用UTF-8编码

二、StringBuilder

String可以用"+"拼接

  • 每次循环都会创建新的字符串对象
  • 绝大部分都是临时对象,浪费内存:
  • 影响GC效率

StringBuilder可以高效拼接字符串

  • StringBuilder是可变对象
  • StringBuilder可以预分配缓冲区

StringBuilder可以进行链式操作

StringBuilder sb =new StringBuilder (1024);
String s = sb.append ("Mr ")
.append (name)
.append("!")
.insert(O, "Hello, ")
.toString() ;

原理是append方法返回了this

super.append(str);

return this;

不需要特别改写字符串"+"操作

编译器在内部自动把多个连续的+操作优化为StringBuilder操作

String s = "Hel1o," + name + "!";

StringBuilder和StringBuffer

  • StringBuilder和StringBuffer接口完全相同
  • StringBuffer是StringBuilder的线程安全版本
  • 没有必要使用StringBuffer(字符串一般很少跨线程拼接)

总结

  • StringBuilder是可变对象,用来高效拼接字符串
  • StringBuilder可以支持链式操作
  • 实现链式操作的关键是返回实例本身
  • StringBuffer是StringBuilder的线程安全版本,很少使用

三、包装类型

原理

定义一个Integer类,包含一个实例 字段int。可以把Integer视为int的包装类型 (wrapper)

public class Integer (
    private int value;
    public Integer (int value) {
        this. value = value;
    }
}
Integer n = null;
Integer n2 = new Integer(99);

转换

int、Integer和String的相互转换

特别注意Integer.getlInteger(String) 是从系统环境中读取系统变量

int i = 100;
Integer n1 = new Integer(i);
Integer n2 = Integer.valueOf(i);
Integer n3 = Integer.valueOf("100") ;
int x1 = n1.intValue() ;
int x2 = Integer.parseInt("1OO") ;
String s = n1.toString();

整数和浮点数包装类型继承自Number 可以利用Number下面的方法相互转换

Number num = new Integer(999) ;
byte b = num.byteValue(); .
int n = num.intValue();
long ln = num.longValue();
float f = num.floatValue();
double d = num.doubleValue();

装箱拆箱

编译器可以自动在int和Integer之间转型:

自动装箱:int -> Integer

自动拆箱:Interge -> int

Integer n = 99; // Integer.valueOf (99)
int i = n;   // n.intValue()
Object[] arr = new Object[1];
arr[O] = 999;   // Integer.valueOf(999)

Integer x = null;
int y = x; // NullPointerException

  • 自动装箱和自动拆箱只发生在编译阶段
  • 装箱和拆箱会影响执行效率
  • 编译后的class代码是严格区分基本类型和引用类型的
  • Integer -> int 执行时可能会报错

静态变量

Boolean t = Boolean.TRUE;
Boolean f = Boolean.FALSE;
int max = Integer.MAX_VALUE; // 2147483647
int min = Integer.MIN_VALUE; // 2147483648
int sizeOfLong = Long.SIZE; // 64 (bits)
int bytesOfLong = Long.BYTES; // 8 (bytes)

总结

JDK的包装类型可以把基本类型包装为class

自动装箱和自动拆箱是编译器完成的(JDK>=1.5)

装箱和拆箱会影响执行效率

注意拆箱时可能发生NullPointerException

四、JavaBean

定义

许多class的定义都符合: - 若干private实例字段 - 通过public方法读写实例字段

public class Person (
    private String name;
    private int age;
    public String getName() {...}
    public void setName (String name)  {...}
    public int getAge()  {...}
    public void setAge (int age)  {...}
)

符合命名规范的class被称为JavaBean - private Type field - public Type getField() - public void setField(Type value)

注意方法名称的大小写

Boolean字段的读方法命名为isXXX():

通常把一组对应的getter和setter称为属性(Property) name属性: - 对应读方法getName() - 对应写方法setName()

总结

JavaBean是一种符合命名规范的class

JavaBean通过: getter/setter来定义属性

属性是一种通用的叫法,并非Java语法规定

可以利用IDE快速生成getter/setter

使用Introspector.getBeanlnfo()获取属性列表

五、枚举

普通定义常量方法

编译器不能检测或检查常量的修改

public class Weekday{
    public static final int SUN = 0;
    public static final String RED = "r";
}

if(day == Weekday.SUN)
if("r".equals(Color.RED))

用enum定义常量

  • 关键字enum定义常量类型
  • 常量本身带有类型信息
  • 使用 == 比较

enum定义的类型实际上是class - 继承自java.lang.Enum - 不能通过new创建实例 - 所有常量都是唯一实例(引用类型) - 可以用于switch语句

public enum Color{
    RED, GREEN, BLUE;    
}
//编译器编译出的class:
public final class Color extends Enum{
    public static final Color RED = new Color () ;
    public static final Color GREEN = new Color () ;
    public static final Color BLUE = new Color () ;

    private Color() {}
}

例子

public enum Weekday {
    SUN, MON, TUE, WED, THU, FRI, SAT;
}

public class Main {

    public static void main(String[] args) {
        for (Weekday day : Weekday.values()) {
            System.out.println(day.name());
        }
        Weekday fri = Weekday.FRI;
        // enum -> String:
        System.out.println("FRI.name() = " + fri.name());
        // 定义时的序号:
        System.out.println("FRI.ordinal() = " + fri.ordinal());
        // String -> enum:
        System.out.println(Weekday.valueOf("FRI").name());
        // 不存在的name:
        Weekday.valueOf("ABC");
    }
}

总结

enum可以定义常量类型,它被编译器编译为:

final class Xxx extends Enum { ... }

name()获取常量定义的字符串,注意不要使用toString()

ordinal()返回常量定义的顺序(无实质意义)

可以为enum类编写构造方法、字段和方法

构造方法申明为private

六、常用工具类

Math:数学计算

Math提供了数学计算的静态方法: - abs/min/max - pow / sqrt / exp / log / log10 - sin / cos / tan / asin / acos

常量: - PI = 3.14159... - E = 2.71828...

Random:生成伪随机数

Math.random()生成一个随机数 - 0<=随机数<1 - 可用于生成某个区间的随机数

// MIN <= R < MAX
long MIN = 1000;
long MAX = 9000 ;
double x2 = Math.random() * (MAX-MIN) + MIN;
double r = (long)x2;

Random()生成一个伪随机数 - nextInt / nextLong / nextFloat... - nextlnt(N)生成不大于N的随机数

Random r = new Random();
r.nextInt();
r.nextInt(10); //生成0-10之间的随机数,不包括10

什么是伪随机数 - 给定种子后伪随机数算法会生成完全相同的序列 - 不给定种子时Random使用系统当前时间戳作为种子

SecureRandom用来创建安全的随机

BigInteger:表示任意大小的整数

BigDecimal:表示任意精度的浮点数

总结

Math:数学计算

Random:生成伪随机数

SecureRandom:生成安全的随机数

BigInteger:表示任意大小的整数

BigDecimal:表示任意精度的浮点数

BigInteger和BigDecimal都继承自Number

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • ACM札记之一

    输入n(n<=100)个整数,按照绝对值从大到小排序后输出。题目保证对于每一个测试实例,所有的数的绝对值都不相等。

    慕白
  • 算法学习之栈与队列

    Stack<E> void push(E) //入栈 E pop() //出栈 E peek() //查看 int getSize() //长度 bool...

    慕白
  • Java常用工具类之字符串

    //创建一个字符串对象mubai,名为s1 String s1 = "mubai"; //创建一个空字符串对象,名为s2 String s2 = new Str...

    慕白
  • PAT 甲级 1003Emergency(Dijkstra最短路)

    1003. Emergency (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序...

    ShenduCC
  • 一道有趣的树状数组题

    Every year, Farmer John's N (1 <= N <= 20,000) cows attend "MooFest",a social ga...

    ACM算法日常
  • 玩转Elasticsearch源码-一张图看懂ES启动流程

    上图中虚线表示进入具体流程,实线表示下一步,为了后面讲解方便每个步骤都加了编号。 先简单介绍下启动流程主要涉及的类:

    左手java右手go
  • 《 动态规划_ 入门_最大连续子序列_HDU_1003 》

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe...

    梅花
  • POJ--1699 Best Sequence(DP+dfs)

    Best Sequence Time Limit: 1000MS Memory Limit: 10000K Total Submissions...

    ShenduCC
  • F2. Animal Observation (hard version)

    time limit per test:3 seconds memory limit per test:512 megabytes inputstandard ...

    某些人
  • UESTC 485 Game(康托展开,bfs打表)

    Game Time Limit: 4000/2000MS (Java/Others) Memory Limit: 65535/65535KB (Ja...

    ShenduCC

扫码关注云+社区

领取腾讯云代金券