常用基础类

一)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. PHP 方法,类与对象的相关函数学习

    1.function_exists function_exists(string)检测函数是否存在,string表示需要检测的函数名称(注意与property_exists,method_exists ...

  2. Nginx详解九:Nginx基础篇之Nginx的访问控制

    基于IP的访问控制:http_access_module 不允许指定网段的用户访问:配置语法:deny address | CIDR | unix: | all;默认状态:-配置方法:http.ser ...

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

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

  4. SQL Server INSET/UPDATE/DELETE的执行计划

    DML操作符包括增删改查等操作方式. insert into Person.Address (AddressLine1, AddressLine2, City, StateProvinceID, Po ...

  5. 函数select、poll

    函数select select函数: int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct ...

  6. android开发默认图标怎么换?

    首先要在资源文件放入想换的图标图片拖到drawable-XX文件夹下, 然后打开AndroidManifest.xml这个配置清单文件找 到application标签里的这句android:icon= ...

  7. debian 下deb包的制作

    http://page.renren.com/601230663/note/817856769?op=next&curTime=1333642042000

  8. jQuery中的extend()方法

    通常我们使用jquery的extend时,大都是为了实现默认字段的覆盖,即若传入某个字段的值,则使用传入值,否则使用默认值.如下面的代码: function getOpt(option){ var _ ...

  9. Centos6中Docker使用中国官方镜像加速

    vi /etc/sysconfig/docker 增加如下内容: other_args="--registry-mirror=https://registry.docker-cn.com&q ...

  10. 1419: Red is good

    题解: 很简单的期望dp 转移方程显然,max一个0就可以了 #include <bits/stdc++.h> using namespace std; #define rep(i,h,t ...