常用基础类

一)String

String内部用一个字符数组表示字符串:

private final char value[];

注意:Java9对此做了优化,采用byte[],如果字符都是ASCII字符,它就可以使用一个字节表示一个字符。

String有的两个构造方法,可以根据参数创建String变量:

//根据参数创建一个新的char数组,
//并使用新的char数组实现String的大部分方法
public String(char value[])
public String(char value[], int offset, int count)

编码相关:

返回字符串给定编码的字节表示:

public byte[] getBytes() //使用系统默认编码
public byte[] getBytes(String charsetName)
public byte[] getBytes(Charset charset)

根据字节和编码创建字符串的构造方法:

public String(byte bytes[], int offset, int length, String charsetName)
public String(byte bytes[], Charset charset)

不可变的String:

String定义为不可变的程序可以更简单、安全、容易理解。

常量字符串:

Java中的字符串常量就是String对象,可以调用String的方法。

在内存中它们被放入一个共享的地方,称为字符串常量池,它保存

所有的常量字符串,每个常量只保存一份,被所有使用者共享。

当通过常量的形式使用字符串的时候,就是使用常量池中的String类型对象。

        String a = "apple";
String b = "apple";
System.out.println(a == b); //true //上面的代码实际上相当于
String c = new String(new char[]{'a', 'p', 'p', 'l', 'e'});
String e = c;
String d = c;
//实际上只有一个String对象,三个变量都指向这个变量
System.out.println(e == d); //true //注意:如果不是通过常量赋值,而是通过new创建,就会不一样
String f = new String("apple");
String g = new String("apple");
System.out.println(f == g);//false 此时比较的是引用地址当然false

因为,String的构造方法:

public String(String original) {
this.value = original.value;
this.hash = original.hash;
}

hash是String的一个实例变量,表示缓存的hashCode值

    public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value; for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}

String与正则:

public String[] split(String regex)
public boolean matches(String regex)
public String replaceFirst(String regex, String replacement)
public String replaceAll(String regex, String replacement)

二)StringBuilder

StringBuffer是线程安全的而StringBuilder不是,但是注意线程安全是有成本的。

1.基本实现原理

StringBuilder父类AbstractStringBuilder封装了一个字符数组:

char value[];

与String不同的是,它不是final的可以被修改,它有一个实例变量表示数组中已经使用的字符个数:

int count;

抽象类的构造方法:

    AbstractStringBuilder(int capacity) {
value = new char[capacity];
}

StringBuilder的构造方法:

public StringBuilder() {
super(16);
}
    public StringBuilder(int capacity) {
super(capacity);
}
    public StringBuilder(String str) {
super(str.length() + 16);
append(str);
}

append方法:

    public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
//确保数组的长度足以容纳新添加的字符
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}
    private void ensureCapacityInternal(int minimumCapacity) {
// 如果数组长度小于需要的长度,则进行扩展
if (minimumCapacity - value.length > 0) {
value = Arrays.copyOf(value,
newCapacity(minimumCapacity));
}
} private int newCapacity(int minCapacity) {
// overflow-conscious code
int newCapacity = (value.length << 1) + 2;
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
? hugeCapacity(minCapacity)
: newCapacity;
}

注意:为了避免每次调用append方法就进行内存分配,指数扩展策略。

在不知道最终需要多长(不知道下次append需要多长)的情况下

,指数扩展策略广泛应用于各种计算机内存分配相关的计算中。

toString方法:

     public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}

String的 + 和 += 运算符:

当String使用这两个运算符的时候,Java编译器一般会生成StringBuilder,

并调用append方法。例如:

String hello = "hello";
hello+=",world";
System.out.println(hello);
//编译器会转换为:
StringBuilder hello = new StringBuilder("hello");
hello.append(",world");
System.out.println(hello.toString());

既然编译器调用了StringBuilder的append方法,那还有什么必要直接使用StringBuilder呢?

因为在复杂的情况下编译器可能会生成过多的StringBuilder。

        String hello = "hello";
for(int i=0;i<3;i++){
hello+=",world";
}
System.out.println(hello); //编译器转换:
/*String hello = "hello";
for(int i=0;i<3;i++){
StringBuilder sb = new StringBuilder(hello);
sb.append(",world");
hello = sb.toString();
}
System.out.println(hello);*/

三)Arrays

数组的优点是比容器的效率更高。

Arrays类包含包含对数组操作的静态方法。

1.toString

输出一个数组的字符串形式,有9个重载方法:

public static String toString(int[] a)
public static String toString(Object[] a)

2.排序

sort()方法:

//每总基本类型都有
public static void sort(int[] a)
public static void sort(double[] a)
//引用类型:但对象要求实现Comparable接口
public static void sort(Object[] a)
public static void sort(Object[] a, int fromIndex, int toIndex)
//或者
public static <T> void sort(T[] a, Comparator<? super T> c)
public static <T> void sort(T[] a, int fromIndex, int toIndex,Comparator<? super T> c)

3.查找

可在已排序的数组中进行二分查找(从中间开始找......):

public static int binarySearch(int[] a, int key)
public static int binarySearch(int[] a, int fromIndex, int toIndex, int key)
public static int binarySearch(Object[] a, Object key)
//自定义比较器,需要和排序时的比较器一致
public static <T> int binarySearch(T[] a, T key, Comparator<? super T> c)

5.多维数组

本质:数组中的每个元素是另一个数组,层层嵌套。

创建多维数组:

int[][][] arr = new int[10][10][10];
int[][] arr = new int[2][];
arr[0] = new int[3];
arr[1] = new int[5];

Arrays数组中的方法都有针对多维数组的方法:

public static String deepToString(Object[] a)
public static boolean deepEquals(Object[] a1, Object[] a2)
public static int deepHashCode(Object a[])

四)日期和时间

由于旧的API被广泛使用,这里介绍Java8之前的日期和时间API

1.基本概念

1)时区

全球一共24个时区,英国格林尼治是0时区,北京是东八区,

0时区也被称为GMT+0时间,GMT是格林尼治标准时间,北京时间就是GMT+8:00。

2)时刻和纪元

所有计算机内部都用一个整数表示时刻,这个整数是距离格林尼治标准时间1970年1月1日0时0分

的毫秒数。这个时间也被称为Epoch Time(纪元时).这个整数表示的是一个时刻,与时区无关,世界

上各个地方都是同一时刻,但各个地区对这一时刻的解读(如年月日时分)可能是不一样的。

2.时间和日期API(Java8以前的)

Date: 表示时刻,即绝对时间,与年月日无关。

Calender:表示年历,Calender是一个抽象类,其中表示公历的子类为Gregorian-Calender。

DateForm:表示格式化,能够将日期和时间与字符串间进行转换,该类也是一个抽象类,最

常用的子类是SimpleDateForm。

TimeZone:表示时区。

Locale:表示国家(地区)和语言。

1)Date

内部用fast变量表示时刻:

private transient long fastTime;//表示距离纪元时的毫秒数

有两个构造方法:

    public Date() {
this(System.currentTimeMillis());
}
public Date(long date) {
fastTime = date;
}

Date中的大部分方法都过时,其中没有过时的有:

public long getTime()//返回毫秒数
public boolean equals(Object obj)//主要是比较内部毫秒数是否相同
public int compareTo(Date anotherDate)//与其他毫秒数进行比较
public boolean before(Date when)
public boolean after(Date when)
public int hashCode()

2)TimeZone

        TimeZone defaultTimeZon = TimeZone.getDefault();
System.out.println(defaultTimeZon.getID()); //Asia/Shanghai TimeZone usTimeZone = TimeZone.getTimeZone("US/Eastern");
System.out.println(usTimeZone.getID()); //US/Eastern
TimeZone unknownTimeZone = TimeZone.getTimeZone("GMT+09:00");
System.out.println(unknownTimeZone.getID()); //GMT+09:00

3)Locale

它主要有两个参数:一个是国家或地区,一个是语言

Locale类中定义了一些静态变量,表示常见的Locale,例如:

        System.out.println(Locale.US); //en_US
System.out.println(Locale.ENGLISH); //en
System.out.println(Locale.TAIWAN); //zh_TW
System.out.println(Locale.CHINESE); //zh
System.out.println(Locale.CHINA); //zh_CN
System.out.println(Locale.SIMPLIFIED_CHINESE); //zh_CN

4)Calendar

该类是日期和时间操作的主要类,它表示与TimeZome和Locale相关的日历信息。

Calendar内部也有一个表示时刻的毫秒数:

protected long time;

还有一个数组表示日历中各个字段的值

protected int fields[];//这个数组长度为17,保存一个日期中各个字段的值

Calendar定义了一些静态变量,表示这些字段如:

Calendar.YEAR表示年

Calender是抽象类,不能直接创建实例:

public static Calendar getInstance()
public static Calendar getInstance(TimeZone zone, Locale aLocale)
//根据提供的TimeZone和Locale创建Calender子类对象

内部,Calendar会将表示时刻的毫秒数,按照TimeZone和Locale对应的年历,

计算各个日历字段的值,存放在fields数组中。

        Calendar calendar = Calendar.getInstance(Locale.CHINA);
System.out.println("YEAR: " + calendar.get(Calendar.YEAR)); //
System.out.println("MONTH: " + calendar.get(Calendar.MONTH)); //
System.out.println("DAY: " + calendar.get(Calendar.DAY_OF_MONTH)); //
System.out.println("Day of week: " + calendar.get(Calendar.DAY_OF_WEEK)); //

Calendar支持Date或者毫秒数设置时间:

public final void setTime(Date date)
public void setTimeInMillis(long millis)

也可根据年月日设置:

public final void set(int year, int month, int date)
public final void set(int year, int month, int date,int hourOfDay, int minute, int second)
public void set(int field, int value)

直接增加或者减少时间:

public void add(int field, int amount)//amount正数表示增加,负数表示减少

Calendar之间也可以进行比较:

public boolean equals(Object obj)
public int compareTo(Calendar anotherCalendar)
public boolean after(Object when)
public boolean before(Object when)

5)DateForm

两个主要方法:

public final String format(Date date)
public Date parse(String source)

DateForm定义了4个静态变量,表示4种风格,不同的风格输出详尽程度不一样。

DateFrom是抽象类,用工厂方法创建实例:

public final static DateFormat getDateTimeInstance()
public final static DateFormat getDateInstance()
public final static DateFormat getTimeInstance()

重载方法接收日期及时间风格和Locale为参数:

DateFormat getDateTimeInstance(int dateStyle, int timeStyle)
DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale)
        Calendar calendar = Calendar.getInstance();
calendar.set(2018, 11, 15, 8, 22);
System.out.println(DateFormat.getDateTimeInstance(DateFormat.LONG,
DateFormat.SHORT, Locale.CHINESE).format(calendar.getTime())); //2018年12月15日 上午8:22

DateForm设置TimeZone:

public void setTimeZone(TimeZone zone)

6)SimpleDateForm

该类是DateForm的子类,与父类的主要不同是,它可以接收一个自定义模式作为参数

        Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 E HH时mm分ss秒");
System.out.println("Now is : " + format.format(calendar.getTime()));
//Now is : 2018年11月14日 星期三 09时31分29秒

其中E表示星期,hh也可表示小时,不过是12小时制的。

3.Java8之前时间和日期API的局限性

1)Date种过时的方法

2)Calendar操作繁琐

API设计失败,要写很多代码,难以计算两个日期之间,比如有几天几个月等等。

3)DateForm的线程安全问题

五)随机

1.Math.random

该静态方法生成一个0到1的随机数(duoble类型),但不包括1和0.

        for (int i = 2; i >= 0; i--) {
System.out.println(Math.random());
/*0.2031695860558771
0.7189188014572521
0.686824037093907 */ //每次随机都不一样哦
}

该方法的实现:

public static double random() {
Random rnd = randomNumberGenerator;
if (rnd == null) rnd = initRNG();
return rnd.nextDouble();
}

2.Random类

该类提供了丰富的随机方法:

        Random random = new Random();
System.out.println(random.nextInt());
System.out.println(random.nextInt(100));
//-809244560
//

nextInt()产生一个随机的int,可能为正数,也可能为负数,nextInt(100)产生随机int,范围为0-100

除了默认的构造方法还有一个接收long类型的种子参数的构造方法:

public Random(long seed)

种子决定了随机产生的序列,种子相同,产生的随机数序列就是相同的。

        Random random = new Random(20160824);
for (int i = 0; i < 5; i++) {
System.out.println(random.nextInt(100));
}

结果为:69  13  13  94  50

这个程序无论执行多少遍,在哪儿执行,结果都是一样的。

在Random类中还可用synchronized public void setSeed(long seed) 方法指定种子。

指定种子是为了实现可重复随机。

如果Random使用默认的构造函数,不传入种子,他会自动生成一个种子,

这个种子数是真正的随机数。

3.随机数的应用

1)随机密码

    //生成6位数字随机密码
public static String randomPassWord() {
char[] chars = new char[6];
Random random = new Random();
for (int i = 0; i < 6; i++) {
chars[i] = (char)(random.nextInt(10) + '0');
}
return new String(chars);
}

生成8位随机验证码,可能包含数字、特殊字符、字母

    private static final String SPECIAL_CHARS = "!@#$%^&*-=_+";
private static char nextChar(Random rnd) {
switch (rnd.nextInt(4)) {
case 0:
return (char) ('a' + rnd.nextInt(26));
case 1:
return (char) ('A' + rnd.nextInt(26));
case 2:
return (char) ('0' + rnd.nextInt(10));
default:
return SPECIAL_CHARS.charAt(rnd.nextInt(SPECIAL_CHARS.length()));
}
}
//生成8位随机密码
public static String randomPassWord() {
char[] chars = new char[8];
Random random = new Random();
for (int i = 0; i < 8; i++) {
chars[i] = nextChar(random);
}
return new String(chars);
}

Java笔记(四)常用基础类的更多相关文章

  1. Java笔记(四)……常量与变量

    常量 常量表示不会改变的数值. Java中常量的分类: 整数常量:所有整数 小数常量:所有小数 布尔型常量:较为特有,只有两个数值,true false 字符常量:将一个数字字母或者符号用单引号(' ...

  2. Java虚拟机四 常用Java虚拟机参数

    主要涉及的知识点: 1.跟踪Java虚拟机的垃圾回收和类加载等信息: 2.配置Java虚拟机的堆空间: 3.配置永久区和Java栈. 4.学习虚拟机的服务器和客户端模式. 1.1 跟踪垃圾回收 Jav ...

  3. CentOS7学习笔记(四) 常用命令记录

    查看命令的帮助信息 man 命令查看帮助信息 在想要获取帮助信息的命令前面加上man即可,例如查看ls命令的帮助信息 [root@localhost ~]# man ls help 命令查看帮助信息 ...

  4. JAVA笔记 **__Netbeans常用快捷键

    sout + Tab      生成输出语句 alt+shift+F 格式化代码 Alt+insert  插入代码(包括构造函数,setter和getter方法等) Ctrl+O或Ctrlt+单击 转 ...

  5. Java学习笔记七 常用API对象三

    一.泛型:简单说就是对对象类型进行限定的技术 public class GenericDemo { public static void main(String[] args){ /*泛型作为1.5版 ...

  6. java之jvm学习笔记四(安全管理器)

    java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...

  7. Java学习笔记四---打包成双击可运行的jar文件

    写笔记四前的脑回路是这样的: 前面的学习笔记二,提到3个环境变量,其中java_home好理解,就是jdk安装路径:classpath指向类文件的搜索路径:path指向可执行程序的搜索路径.这里的类文 ...

  8. Java加密与解密笔记(四) 高级应用

    术语列表: CA:证书颁发认证机构(Certificate Authority) PEM:隐私增强邮件(Privacy Enhanced Mail),是OpenSSL使用的一种密钥文件. PKI:公钥 ...

  9. 【转】Verilog HDL常用建模方式——《Verilog与数字ASIC设计基础》读书笔记(四)

    Verilog HDL常用建模方式——<Verilog与数字ASIC设计基础>读书笔记(四) Verilog HDL的基本功能之一是描述可综合的硬件逻辑电路.所谓综合(Synthesis) ...

随机推荐

  1. ERROR 2002 (HY000): Can't connect to local MySQL server through socket '***' (2)

    有时候,当我们使用“mysql”.“mysqladmin”.“mysqldump”等命令管理数据库时,服务器抛出类似如下错误: ERROR (HY000): Can't connect to loca ...

  2. Linux下安装软件命令详解

    ---------------------------------------------------------------- 或许你对于linux还不够了解,但是一旦你步入公司后,你就会发现lin ...

  3. python 给对象绑定属性和方法和__slots__的使用

    # 以c语言为主是静态语言,运行之前先编译,在运行的过程中不允许编辑代码# 在运行的过程中,可以改变,可以添加属性,就是属于动态语言(python) # python动态的添加属性以及方法class ...

  4. paython3-练习

    在文本每行末尾加; f = open(r'D:\test1\1.txt','rb') w = open(r'D:\test1\2.txt','wb') for line in f.readlines( ...

  5. 20165323 2017-2018-2 《Java程序设计》课程总结

    一.每周作业链接汇总 预备作业1:20165323 我期望的师生关系 预备作业2:20165323 学习基础与C语言学习心得 预备作业3:20165323 预备作业三 第一周作业:20165323&l ...

  6. mysql查看工具——mysql profiler sql

    http://www.profilesql.com/download/ 开发同学的福利--mysql监控工具sqlprofiler,类似sqlserver的profiler工具 https://www ...

  7. EF Core MYSQL 生成表映射配置问题

    Model表 public class Goods { public string ID { get; set; } public string CreatedBy { get; set; } pub ...

  8. rabbitmq的安装与使用

    1.RabbitMQ的安装,rabbitmq为erlang语言开发,所以先安装erlang语言开发包,现在电脑一般都是64位的,所以下载64位的都行了.红色框可以选择版本,箭头选择64位的进行下载.下 ...

  9. Tensorflow name_scope

    在 Tensorflow 当中有两种途径生成变量 variable, 一种是 tf.get_variable(), 另一种是 tf.Variable(). 使用tf.get_variable()定义的 ...

  10. lojround6

    花团 线段树分治裸题 给出了结束时间跟离线没区别 「LibreOJ Round #6」花火 首先在第一次使用交换是显然的 然后统计逆序对暴力是n^2的(前缀和优化) 因为交换两个点改变的只有x< ...