目录
4.1.7 StringBuffer和Stringbuilder类
4、数组、常用类的使用
4.1 数组
所谓数组,是有序的元素序列,用于存储不同或相同类型的数据或引用对象。
4.1.1 数组创建的几种方式
声明:
dataType[] arrayRefVar; // 首选的方法
dataType arrayRefVar[]; // 效果相同,但不是首选方法
创建:
dataType[] arrayRefVar= new dataType[size]
dataType[] arrayRefVar = {value0, value1, ..., valuek};
dataType[] arrayRefVar= new dataType[]{value0, value1, ..., valuek}
在Java中允许长度为0的数组,所以在编写一个结果是数组的方法时,如果返回结果是空,可以创建长度为0的数组【new type[0]】
4.1.2 foreach 循环
JDK 1.5 引进了一种新的循环类型,被称为 foreach 循环或者加强型循环,它能在不使用下标的情况下遍历数组。
public class TestArray {
public static void main(String[] args) {
double[] myList = {1.9, 2.9, 3.4, 3.5};
// 打印所有数组元素
for (double element: myList) {
System.out.println(element);
}
}
}
4.1.3 多维数组
多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组
String [][] = new String [3][4] 注意:定义数组的时候,后面可以没有数字,但是第一个数组必须要说明是几,也就是说可以
String [][] = new String [3][] 去使用
二维数组可以看做为几行几列的一维数组,以此类推,多维数组(n)就是几行几列的(n-1)的数组。
int a[][] = new int[2][3];
String s[][] = new String[2][];
s[0] = new String[2];
s[1] = new String[3];
s[0][0] = new String("Good");
s[0][1] = new String("Luck");
s[1][0] = new String("to");
s[1][1] = new String("you");
s[1][2] = new String("!");
4.1.4 Arrays类
java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的。
具有以下功能(常用功能):
- 给数组赋值:通过 fill 方法。
- 对数组排序:通过 sort 方法,按升序。
- 比较数组:通过 equals 方法比较数组中元素值是否相等。
- 查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作。
- 复制新的数组:copyOf:复制出新的数组,复制长度由 newLength 决定,长度可大于被复制数组的长;copyOfRange:复制指定下标范围内的值
- 打印成字符串:字符串表示由数组元素的列表组成,括在方括号( "[]" )中。 相邻的元素由字符", " (逗号后跟一个空格)分隔开。 元素被转换为字符串由String.valueOf(short)。 返回"null"如果a是null。
4.1.5 数组排序
1、冒泡排序
//1、冒泡排序规则:将数据的最大值放到最后,数组的最后面就是水面,最大值依次浮出
public int[] bubbleSort(int[] arr){
for(int i = 0;i < arr.length;i++){
//比较两个相邻的元素
for(int j = 0;j < arr.length-i-1;j++){
if(arr[j] > arr[j+1]){
int t = arr[j];
arr[j] = arr[j+1];
arr[j+1] = t;
}
}
}
return arr;
}
2、直接选择排序(选择出循环中最小的,放到数组的前面,与冒泡不同的是,它不是依次交换而是最后将位置交换)
public static void selectionSort(long[]arr){
long temp = 0;
for(int i=0;i<arr.length-1;i++){
int min=i;
for(int j=i;j<arr.length-1;j++){
if(arr[min]>arr[j+1]){
min = j+1;
}
}
if(min!=i){
temp = arr[min];
arr[min] = arr[i];
arr[i] = temp;
}
}
}
3、插入排序
/**
* 插入排序
* 规则:与前面的值进行比较,插入到比自己小和大的中间
* @param arr
*/
public static void insertSort(long arr[]){
long temp =0;
for(int i=1;i<arr.length;i++){
temp =arr[i];
int j = i;
while(j>0&&arr[j-1]>=temp){
arr[j]=arr[j-1];
j--;
}
arr[j] =temp;
}
}
4、二分法排序
//二分查找
public static int binarySearch(int array[],int low,int high,int temp)
{
int mid=0;
while(low<=high)
{
mid=(low+high)/2;
if(array[mid]<temp&&temp<=array[mid+1])
return (mid+1);
else if(array[mid]<temp)
low = mid + 1;
else
high = mid -1;
}
return high;
}
//二分排序
public static void binarySort(int array[],int size)
{
int i,j,k,temp;
for(i=1;i<size;i++)
{
temp=array[i];
if(array[i]<array[0])
k=0;
else
k = binarySearch(array,0,i,temp);
for(j=i;j>k;j--)
{
array[j]=array[j-1];
}
array[k]=temp;
System.out.println(Arrays.toString(array));
}
}
4.1.5 Object类
Object类是所有类的超类,也是缺省类。如果一个类没有用extends明确指出继承于某个类,那么它默认继承Object类。
可以使用Object类型的变量可以用于引用任何类型的变量。在Java中,只有基本类型不是对象,例如数值、字符、布尔,但是他们的包装类属于继承于Object类。
Object类的方法
返回类型 | 方法 |
---|---|
protected Object | clone() 创建并返回此对象的副本。 |
boolean | equals(Object obj) 指示一些其他对象是否等于此。 |
protected void | finalize() 当垃圾收集确定不再有对该对象的引用时,垃圾收集器在对象上调用该对象。 |
类<?> | getClass() 返回此 |
int | hashCode() 返回对象的哈希码值。 |
void | notify() 唤醒正在等待对象监视器的单个线程。 |
void | notifyAll() 唤醒正在等待对象监视器的所有线程。 |
String | toString() 返回对象的字符串表示形式。 |
void | wait() 导致当前线程等待,直到另一个线程调用该对象的 |
void | wait(long timeout) 导致当前线程等待,直到另一个线程调用 |
void | wait(long timeout, int nanos) 导致当前线程等待,直到另一个线程调用该对象的 |
4.1.6 String类
String
类代表字符串。 Java程序中的所有字符串文字(例如"abc"
)都被实现为此类的实例。字符串不变; 它们的值在创建后不能被更改。 字符串缓冲区支持可变字符串。 因为String对象是不可变的,它们可以被共享。 例如:String str = "abc"。
String类的不可继承
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
String的成员变量
/** The value is used for character storage. */ private final char value[]; /** Cache the hash code for the string */ private int hash; // Default to 0 /** use serialVersionUID from JDK 1.0.2 for interoperability */ private static final long serialVersionUID = -6849794470754667710L; /** * Class String is special cased within the Serialization Stream Protocol. * * A String instance is written into an ObjectOutputStream according to * <a href="{@docRoot}/../platform/serialization/spec/output.html"> * Object Serialization Specification, Section 6.2, "Stream Elements"</a> */ private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0];
从源码看出String底层使用一个字符数组来维护的。
创建字符串的两种方式:
1、String str =“abc”
2、String str= new String("abc");
第一种方式:在内存堆中直接开辟一个内存,并进入对象池。
第二种方式:现在内存中开辟一块内存,创建“abc”,然后new 的时候又开辟了一块内存,前一块内存中匿名对象变成了垃圾。
综上:一般都使用第一种方式,只开辟一块内存,并且入池。
String的不可变:
String因为是final修饰,所以值不可变。当然我们可以修改当前对象引用的地址,例如
String str =“abc”
str = “345”;
现在str确实为“345”,但是内存中还存在着“abc”,所以使用String时,总是变化的话,会很占内存,推荐使用StringBuffer来拼接字符串。
不可变优点:
- 方便做hash中的key
- String pool的需要
- 安全性
- 线程安全
String使用的设计模式
亨元模式
一个系统中如果有多处用到了相同的一个元素,那么我们应该只存储一份此元素,而让所有地方都引用这一个元素,Java中String部分就是根据享元模式设计的,而那个存储元素的地方就叫做“字符串常量池 - String Pool
构造方法:
方法 | 解释 |
String(byte[] bytes) | 通过使用平台的默认字符集解码指定的字节数组来构造新的 String 。 |
String(byte[] bytes, Charset charset) | 构造一个新的String 由指定用指定的字节的数组解码charset |
String(byte[] bytes, int offset, int length) | 通过使用平台的默认字符集解码指定的字节子阵列来构造新的 String 。 |
String(char[] value, int offset, int count) | 分配一个新的 String ,其中包含字符数组参数的子阵列中的字符。 |
String(StringBuffer buffer) | 分配一个新的字符串,其中包含当前包含在字符串缓冲区参数中的字符序列。 |
成员方法:
返回类型 | 方法名称 |
---|---|
char | charAt(int index) 返回 |
int | codePointAt(int index) 返回指定索引处的字符(Unicode代码点)。 |
int | codePointBefore(int index) 返回指定索引之前的字符(Unicode代码点)。 |
int | codePointCount(int beginIndex, int endIndex) 返回此 |
int | compareTo(String anotherString) 按字典顺序比较两个字符串。 |
int | compareToIgnoreCase(String str) 按字典顺序比较两个字符串,忽略病例差异。 |
String | concat(String str) 将指定的字符串连接到该字符串的末尾。 |
boolean | contains(CharSequence s) 当且仅当此字符串包含指定的char值序列时才返回true。 |
boolean | contentEquals(CharSequence cs) 将此字符串与指定的CharSequence进行 |
boolean | contentEquals(StringBuffer sb) 将此字符串与指定的StringBuffer进行 |
static String | copyValueOf(char[] data) 相当于 |
static String | copyValueOf(char[] data, int offset, int count) |
boolean | endsWith(String suffix) 测试此字符串是否以指定的后缀结尾。 |
boolean | equalsIgnoreCase(String anotherString) 将此 |
static String | format(Locale l, String format, Object... args) 使用指定的区域设置,格式字符串和参数返回格式化的字符串。 |
static String | format(String format, Object... args) 使用指定的格式字符串和参数返回格式化的字符串。 |
byte[] | getBytes() 使用平台的默认字符集将此 |
byte[] | getBytes(Charset charset) 使用给定的charset将该 |
void | getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin) 已弃用 此方法无法将字符正确转换为字节。 从JDK 1.1开始,首选的方法是通过 |
byte[] | getBytes(String charsetName) 使用命名的字符集将此 |
void | getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) 将此字符串中的字符复制到目标字符数组中。 |
int | hashCode() 返回此字符串的哈希码。 |
int | indexOf(int ch) 返回指定字符第一次出现的字符串内的索引。 |
int | indexOf(int ch, int fromIndex) 返回指定字符第一次出现的字符串内的索引,以指定的索引开始搜索。 |
int | indexOf(String str) 返回指定子字符串第一次出现的字符串内的索引。 |
int | indexOf(String str, int fromIndex) 返回指定子串的第一次出现的字符串中的索引,从指定的索引开始。 |
boolean | isEmpty() 返回 |
int | lastIndexOf(int ch) 返回指定字符的最后一次出现的字符串中的索引。 |
int | lastIndexOf(int ch, int fromIndex) 返回指定字符的最后一次出现的字符串中的索引,从指定的索引开始向后搜索。 |
int | lastIndexOf(String str) 返回指定子字符串最后一次出现的字符串中的索引。 |
int | lastIndexOf(String str, int fromIndex) 返回指定子字符串的最后一次出现的字符串中的索引,从指定索引开始向后搜索。 |
boolean | matches(String regex) 告诉这个字符串是否匹配给定的 regular expression 。 |
String | replace(char oldChar, char newChar) 返回从替换所有出现的导致一个字符串 |
String | replace(CharSequence target, CharSequence replacement) 将与字面目标序列匹配的字符串的每个子字符串替换为指定的字面替换序列。 |
String | replaceAll(String regex, String replacement) 用给定的替换替换与给定的 regular expression匹配的此字符串的每个子字符串。 |
String[] | split(String regex) 将此字符串分割为给定的 regular expression的匹配。 |
String[] | split(String regex, int limit) 将这个字符串拆分为给定的 regular expression的匹配。 |
boolean | startsWith(String prefix) 测试此字符串是否以指定的前缀开头。 |
boolean | startsWith(String prefix, int toffset) 测试在指定索引处开始的此字符串的子字符串是否以指定的前缀开头。 |
CharSequence | subSequence(int beginIndex, int endIndex) 返回一个字符序列,该序列是该序列的子序列。 |
String | substring(int beginIndex) 返回一个字符串,该字符串是此字符串的子字符串。 |
String | substring(int beginIndex, int endIndex) 返回一个字符串,该字符串是此字符串的子字符串。 |
char[] | toCharArray() 将此字符串转换为新的字符数组。 |
String | toLowerCase() 将所有在此字符 |
String | toLowerCase(Locale locale) 将所有在此字符 |
String | toUpperCase() 将所有在此字符 |
String | toUpperCase(Locale locale) 将所有在此字符 |
String | trim() 返回一个字符串,其值为此字符串,并删除任何前导和尾随空格。 |
static String | valueOf(boolean b) 返回 |
static String | valueOf(Object obj) 返回 |
4.1.7 StringBuffer和Stringbuilder类
当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。
StringBuffer和Stringbuilder的成员方法
返回值 | 方法名称 |
---|---|
StringBuffer | append(boolean b) 将 |
StringBuffer | append(Object obj) 追加 |
StringBuffer | append(StringBuffer sb) 将指定 |
StringBuffer | appendCodePoint(int codePoint) 将 |
int | capacity() 返回当前容量。 |
char | charAt(int index) 返回 |
StringBuffer | delete(int start, int end) 删除此序列的子字符串中的字符。 |
StringBuffer | deleteCharAt(int index) 删除 |
int | indexOf(String str) 返回指定子字符串第一次出现的字符串内的索引。 |
int | indexOf(String str, int fromIndex) 返回指定子串的第一次出现的字符串中的索引,从指定的索引开始。 |
StringBuffer | insert(int offset, boolean b) 在此序列中插入 |
int | lastIndexOf(String str) 返回指定子字符串最右边出现的字符串内的索引。 |
int | lastIndexOf(String str, int fromIndex) 返回指定子字符串最后一次出现的字符串中的索引。 |
StringBuffer | replace(int start, int end, String str) 用指定的String中的字符替换此序列的子字符串中的 |
StringBuffer | reverse() 导致该字符序列被序列的相反代替。 |
String | substring(int start) 返回一个新的 |
String | substring(int start, int end) 返回一个新的 |
面试题:
String 、StringBuffer、StringBuilder的区别?
相同点:String、StringBuff 与 StringBuilder 都可以对字符串进行操作。
字符串操作效率上看 StringBuilder > StringBuffer > String
效率的区别分析:
- String 在设计的时候处于安全和性能的考虑,设置为 final 修饰,长度不可变,每次在常量池新增一个字符串都是重新 new 一个对象,原来的对象没有引用后等待 GC 回收,所以效率比较慢。
- StringBuilder 和 StringBuffer 都是可变长度的字符串,都继承了
AbstractStringBuilder
。那么造成它们使用区别的原因分析源码可以知道。StringBuffer 的方法都加了synchronized
同步锁,代表线程安全。而StringBuilder 则没有加锁,所以 StirngBuilder 的效率要优于 StirngBuffer。使用总结:
- 如果要操作少量的数据用 = String
- 单线程操作字符串缓冲区 下操作大量数据 = StringBuilder(线程非安全)
- 多线程操作字符串缓冲区 下操作大量数据 = StringBuffer(有buff就是安全,这个是线程安全的)
- 最后使用时可以指定StringBuffer的初始化长度,因为默认长度为16,超出后新建数组,将前面的数组复制过来,避免自动增长来提高性能。
4.1.8 包装类
概念:
包装类(Wrapper Class): Java是一个面向对象的编程语言,但是Java中的八种基本数据类型却是不面向对象的,为了使用方便和解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八种基本数据类型对应的类统称为包装类(Wrapper Class),包装类均位于java.lang包。、
包装类与基本类型的对应关系:
- char —> Character
- boolean —> Boolean
- byte—> Byte
- short—> Short
- long—> Long
- int —> Integer
- float—> Float
- double—> Double
下面学习平时开发使用较多的方法
Character类
序号 | 方法与描述 |
---|---|
1 | isLetter() 是否是一个字母 |
2 | isDigit() 是否是一个数字字符 |
3 | isWhitespace() 是否是一个空格 |
4 | isUpperCase() 是否是大写字母 |
5 | isLowerCase() 是否是小写字母 |
6 | toUpperCase() 指定字母的大写形式 |
7 | toLowerCase() 指定字母的小写形式 |
8 | toString() 返回字符的字符串形式,字符串的长度仅为1 |
抽象类 Number 是父类,Number 的子类必须提供将表示的数值转换 成 byte、double/float/long/int/short 的方法。Number 类的方法被 Number 的各子类所实现,常用方法如下:
Number 类的方法
方法 | 返回值 | 功能描述 |
---|---|---|
byteValue() | byte | 以 byte 形式返回指定的数值 |
intValue() | int | 以 int 形式返回指定的数值 |
floatValue() | float | 以 float 形式返回指定的数值 |
shortValue() | short | 以 short 形式返回指定的数值 |
longValue() | long | 以 long 形式返回指定的数值 |
doubleValue() | double | 以 double 形式返回指定的数值 |
4.1.9 Math类
Math
类包含执行基本数字运算的方法,如基本指数,对数,平方根和三角函数。
返回值 | 方法名称 |
---|---|
static double | abs(double a) 返回值为 |
static float | abs(float a) 返回 |
static double | acos(double a) 返回值的反余弦值; 返回的角度在0.0到pi的范围内。 |
static double | floor(double a) 返回小于或等于参数的最大(最接近正无穷大) |
static double | max(double a, double b) 返回两个 |
static float | max(float a, float b) 返回两个 |
static float | min(float a, float b) 返回两个 |
static double | pow(double a, double b) 将第一个参数的值返回到第二个参数的幂。 |
static double | random() 返回值为 |
static double | rint(double a) 返回与参数最接近值的 |
static long | round(double a) 返回参数中最接近的 |
4.1.10 Random类
random类用于生成随机数的类。许多应用程序会发现方法Math.random()
使用起来更简单。
返回值 | 方法 |
---|---|
DoubleStream | doubles() 返回一个有效的无限流的伪随机 |
IntStream | ints() 返回一个有效的无限流的伪 |
IntStream | ints(int randomNumberOrigin, int randomNumberBound) 返回一个有效的无限流伪 |
protected int | next(int bits) 生成下一个伪随机数。 |
boolean | nextBoolean() 返回下一个伪随机数,从这个随机数发生器的序列中均匀分布 |
void | nextBytes(byte[] bytes) 生成随机字节并将它们放入用户提供的字节数组中。 |
double | nextDouble() 返回下一个伪随机数,从这个随机数发生器的序列中 |
float | nextFloat() 返回下一个伪随机数,从这个随机数发生器的序列中 |
double | nextGaussian() 从该随机数发生器的序列返回下一个伪随机数,高斯(“正”)分布 |
int | nextInt() 返回下一个伪随机数,从这个随机数发生器的序列中均匀分布 |
int | nextInt(int bound) 返回伪随机的,均匀分布 |
long | nextLong() 返回下一个伪,均匀分布 |
void | setSeed(long seed) 使用单个 |
4.1.11 System类
System
类提供的System
包括标准输入,标准输出和错误输出流; 访问外部定义的属性和环境变量; 一种加载文件和库的方法; 以及用于快速复制阵列的一部分的实用方法。
返回值 | 方法 |
---|---|
static long | currentTimeMillis() 返回当前时间(以毫秒为单位)。 |
static void | exit(int status) 终止当前运行的Java虚拟机。 |
static void | gc() 运行垃圾回收器。 |
static Map<String,String> | getenv() 返回当前系统环境的不可修改的字符串映射视图。 |
static String | getenv(String name) 获取指定环境变量的值。 |
static Properties | getProperties() 确定当前的系统属性。 |
static String | getProperty(String key) 获取指定键指示的系统属性。 |
static String | getProperty(String key, String def) 获取指定键指示的系统属性。 |
static SecurityManager | getSecurityManager() 获取系统安全界面。 |
static void | setSecurityManager(SecurityManager s) 设置系统安全性。 |
4.1.12 BigInteger、BigDecimal类
一般来说,BigInteger用的不是很多,BigDecimal用的稍微多一点,就比如说JDBC中,如果一个字段的数据库类型是Number, 那么getObject().getClass()的结果是java.math.BigDecimal
BigInteger相比Integer的确可以用big来形容。它是用于科学计算,Integer只能容纳一个int, 所以最大值也就是2的31次访减去1,十进制为2147483647,如果需要计算更大的数,那么31位显然是不够用了,BigInteger能够容纳的位数那可就大了,理论上可以无限大。除了容量大之外,BigInteger还封装了一些常见的操作,比如+-*/的基本操作,还有绝对值,相反数,最大公约数,是否是质数等等的运算。
4.1.13 Date、DateFormat类
java.util.Date
返回值 | 方法 |
---|---|
boolean | after(Date when) 测试此日期是否在指定日期之后。 |
boolean | before(Date when) 测试此日期是否在指定日期之前。 |
Object | clone() 返回此对象的副本。 |
int | compareTo(Date anotherDate) 比较两个日期进行订购。 |
boolean | equals(Object obj) 比较两个日期来平等。 |
java.sql.Date extends java.util.Date
两者区别
java.util.Date 类型写到数据库后存储的值可以到秒,java.sql.Date 类型的写入后只能到日期。
DateFormate类
DateFormat
是日期/时间格式化子类的抽象类,它以语言无关的方式格式化和分析日期或时间。
时间转换的工具类
返回值 | 方法 |
---|---|
String | format(Date date) 将日期格式化成日期/时间字符串。 |
abstract StringBuffer | format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) 将日期格式化成日期/时间字符串。 |
StringBuffer | format(Object obj, StringBuffer toAppendTo, FieldPosition fieldPosition) 覆盖格式。 |
Calendar | getCalendar() 获取与此日期/时间格式化程序关联的日历。 |
static DateFormat | getDateInstance() |
static DateFormat | getDateInstance(int style) |
abstract Date | parse(String source, ParsePosition pos) 根据给定的解析位置解析日期/时间字符串。 |
Object | parseObject(String source, ParsePosition pos) 从字符串中解析文本以产生一个 |