常用类
包装类(Wrapper)
-
分类
- 针对霸总基本数据类型相应的引用类型——包装类
- 有了类的特点,就可以调用类中的方法
基本数据类型 包装类 boolean Boolean char Character byte Byte int Integer long Long float Float double Double short Short Byte…Short,他们的父类都是Number
-
包装类和基本数据类型的转换
-
jdk5之前手动装箱和拆箱方式
int n = 100; //jdk5之前手动装箱 Integer integer = new Integer(n); Integer valueOf = Integer.valueOf(n); //手动拆箱 int m = integer.intValue();
-
jdk5及之后是自动装箱和拆箱方式
//jdk5及之后自动装箱 int a = 100; Integer integer = a;//底层还是 Integer.valueOf(a) //自动拆箱 int b = integer;//底层使用的还是integer.intValue()
-
其他包装类的使用方法与int相同
-
-
三元运算符要看做一个整体,有int和double,精度按double来
-
包装类和String相互转换
Integer integer = 100;//自动装箱 //Integer和String互相转换 //Integer=>String //方式1 String s1 = integer + ""; //方式2 String s2 = integer.toString(); //方式3 String s3 = String.valueOf(integer); //String=>Integer String str = "123"; //方式1 Integer i1 = Integer.parseInt(str); //方式2 Integer i2 = new Integer(str);
-
Integer和Char包装类的常用方法
-
Integer m = 1; Integer n = 1; System.out.println(m == n);//T //当m和n在-128-127之间时,直接返回一个Integer对象,所以m和n是同一个对象,当不在次范围内时,就要new一个Integer,m和n就是两个对象了
-
只要有基本数据类型,==判断的是二者值是否相等
String类
-
String的理解和创建对象
-
String对象用于保存字符串,也就是一组字符序列
-
字符串常量对象是用双引号括起的字符序列,String str = “ak47”; "ak47"就是常量,str是变量
-
String使用的是Unicode编码,一个字符(不区分字母还是汉字)占两个字节
-
String类的常用构造器
String s1 = new String(); String s2 = new String(String origianl); String s3 = new String(char[] a); String s4 = new String(char[],int startIndex,int count); String s5 = new String(byte[] b);
-
String类实现了Serializable接口,说明String可串行化,可以在网络传输
-
String 类实现了Comparable接口,说明String对象可以比较,compareTo()方法
-
String是final类,不能被其他类继承
-
String有属性private final char value[],用于存放字符串内容,value是一个final类型,不可以修改(内容可改,地址不可修改=>也就是不能让value再指向其他的对象)
-
-
创建String对象的两种方式
-
直接赋值 String s = “aaaaa”;
先从常量池查看是否有“aaaaa“的数据,如果有,直接指向,如果没有则重新创建再指向。最终s指向的是常量池的空间地址。
-
调用构造器String s = new String(“aaaaa”)
先在堆中创建空间,里面维护了value属性,指向常量池的“aaaaa‘空间,如果常量池没有则重新创建,如果有则直接通过value指向,最终s指向的是堆中的空间地址,value指向的是常量池的地址
-
-
intern方法
最终返回的是常量池中字符串的地址
-
字符串的特性
-
String是一个final类,代表不可变的字符序列
-
字符串是不可变的。一个字符串对象一旦被分配,其内容是不可变的。
-
String s1 = "Hello"; s1 = "haha"; //创建了两个对象,先看常量池中有没有"haha",如果有s1直接指向,如果没有就新建一个"haha"再指向,并没有改变"Hello" String a = "hello" + "abc"; //编译器会优化,等价于String a = "helloabc"; 所以只创建了一个对象。编译器判断创建的常量池对象是否有引用指向,没有的话肯定说明没人用,创建一个最终的就可以了。 String a = "hello";//创建a对象 String b = "abc";//创建b对象 String c = a + b; //1、先创建一个StringBuffer //2、执行sb.append("hello") //3、执行sb.append("abc") //4、执行String c = sb.toString() //其实最后是c指向堆中的对象(String) value[] ->常量池中的"helloabc" String c1 = "ab" + "cd"; //常量相加,看的是池 String c1 = a + b; //变量相加,是在堆中
-
-
String类的常见方法
String类是保存字符串常量的,每次更新都需要开辟空间,效率较低
equals() //区分大小写,判断内容是否相等 equalslgnoreCase()//忽略大小写的判断内容是否相等 length()//获取字符的个数,字符串的长度 indexOf()//获取字符在字符串中第1次出现的索引,索引从0开始,如果找不到,返回-1,参数可以是字符也可以是字符串 lastIndexOf()//获取字符在字符串中最后1次出现的索引,索引从0开始,如找不到,返回-1 substring()//截取指定范围的子串 //(6):从索引6开始,截取后面所有的内容 //(0,5):从索引0开始截取,截取到索引为5-1=4的字符 trim//去前后空格 charAt()//获取某索引处的字符,注意不能使用Str[index] 这种方式; toUpperCase()//转大写 toLowerCase()//转小写 concat()//拼接 replace("","")//替换字符串中的字符,s2 = s1.replace,s1没有变化,s2是替换后的内容 split()//分割字符串,对于某些分割字符,我们需要转义比如| \\等,split(",")指把字符串按逗号分割,返回字符串数组;在对字符串进行分割时,如果有特殊字符,需要加转义字符\ compareTo()//比较两个字符串的大小,如果前者大返回正数,如果后者大返回负数,相等返回0;返回第一个不同的字符的差,如果长度不等,其中一个字符串是另一个的字串,则返回长度差 //1、如果长度相同,每个字符也相同,返回0 //2、如果长度相同或不相同,但是在进行比较时可以区分大小,返回第一个不同的字符的差 //3、如果长度不等,其中一个字符串是另一个的字串,则返回长度差 toCharArray()//转换成字符数组 format()//格式字符串,占位符如下: //%s字符串 %c字符 %d整型 %.2f浮点型 //占位符由后面的变量替换
StringBuffer类
-
基本介绍
- java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删
- 很多方法与String相同,但是StringBuffer是可变长度的
- StringBuffer是一个容器
- StringBuffer的直接父类是AbstractStringBuffer
- StringBuffer实现了Serializable,即StringBuffer的对象可以串行化
- 在父类中,AbstractStringBuffer有属性char[] value,不是final,value数组存放字符串内容,引出存放在堆中的
- StringBuffer是一个final类,不能被继承
-
String VS StringBuffer
-
String保存的是字符串常量,里面的值不能更改,每次String类的更新实际上就是更改地址,效率较低
-
StringBuffer保存的是字符串变量,里面的值可以更改,每次StringBuffer的更新实际上可以更新内容,不用每次更新地址,效率较高
//char[] value; //这个放在堆
-
因为StringBuffer的字符序列是存放在char [] value,所以变化时不用每次都更换地址(即不是每次都创建新对象)所以效率高于String
-
-
StringBuffer的构造器
- StringBuffer( ) // 创建一个大小为16的char[],用于存放
- StringBuffer(CharSequence seq) //构造一个字符串缓冲区,它包含与指定的CharSequence相同的字符
- StringBuffer(int capacity) //capacity 容量 构造一个不带字符但具有初始容量的字符串缓冲区,即对char[]大小进行指定
- StringBuffer(String str) //构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容(char[]数组长度增加了16)
-
String与StringBuffer互相转换
-
String==>StringBuffer
String str = "a"; //方式一,使用构造器 //返回的是StringBuffer对象,对str没有任何影响 StringBuffer str1 = new StringBuffer("str"); //方式二 使用append()方法 StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append(str);
-
StringBuffer==>String
//方式一 使用toString方法 StringBuffer strb = new StringBuffer("a"); String strstr = strb.toString(); //方式二,使用构造器 String str2 = new String(strb); //strb为空时会报空指针异常,因为源码需要用到strb.length()
-
-
StringBuffer常用方法
- append()–增加,如果参数为空,调用appendNull方法,StringBuffer内容为“null”
- delete(11,14)–删除11-14的字符,[11,14),包含11不含14
- replace(9,11,“a”)–使用a替换9-11的字符[9-11),包含9不包含11
- indexOf(“qaq”)–查找指定的字串在字符串中第一次出现的索引,如果找不到返回-1
- insert(9,“ak”)–在索引为9的位置插入ak,原来索引为9的内容自动后移
- length()–返回长度
StringBuilder类
-
基本介绍
- 一个可变的字符序列。此类提供一个与StringBuffer兼容的API,但不保证同步(StringBuilder不是线程安全)。该类被设计用作 StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。
- 在StringBuilder上的主要操作是append和 insert方法,可重载这些方法,以接受任意类型的数据。
-
常用方法
与StringBuffer方法一样
- StringBuilder继承 AbstractStringBuilder类
- 实现了Serializable ,,说明StringBuilder对象是可以串行化(对象可以网络传输,可以保存到文件)
- StringBuilder是final类,不能被继承
- StringBuilder对象字符序列,仍然是存放在其父类 AbstractStringBuilder的 char[] value;因此,字符序列是堆中
- StringBuilder 的方法,没有做互斥的处理,即没有synchronized关键字,因此在单线程情况下使用
-
String vs StringBuffer vs StringBuilder
-
StringBuilder 和 StringBuffer非常类似,均代表可变的字符序列,而且方法也一样
-
String:不可变字符序列,效率低,但是复用率高(一个常量池的字符串可以有多个引用)。
-
StringBuffer:可变字符序列、效率较高(增删)、线程安全(有synchronized关键字,同步的意思)
-
StringBuilder:可变字符序列、效率最高、线程不安全
-
String使用注意说明:
String s = "a";//创建了一个字符串 s += "b";//实际上原来的"a"字符串对象已经丢弃了,现在又产生了一个字符串s+"b”(也就是"ab")。 //如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大影响程序的性能=> //结论:如果我们对String 做大量修改,不要使用String,用StringBuffer
-
效率测试
StringBuilder > StringBuffer > String
-
-
String、StringBuffer、StringBuilder使用原则
1.如果字符串存在大量的修改操作,一般使用 StringBuffer 或StringBuilder
2.如果字符串存在大量的修改操作,并在单线程的情况,使用StringBuilder
3.如果字符串存在大量的修改操作,并在多线程的情况,使用 StringBuffer
4、如果我们字符串很少修改,被多个对象引用,使用String, 比如配置信息等
Math类
常见的方法(静态)
-
abs绝对值
-
pow求幂
-
ceil向上取整,返回大于等于该参数的最小整数(转成double)
-
floor向下取整,返回小于等于该参数的最大整数(转成double)
-
round四舍五入 相当于Math.floor(参数+0.5)
-
sqrt求开方,参数为负返回NaN
-
random求随机数 返回的是0 <= x < 1之间的随机小数
//返回a-b之间的整数,a<=x<=b
//int num = (int) (a + Math.random() * (b - a + 1))
-
max求两个数的最大值
-
min求两个数的最小值
Arrays类
包含一系列静态方法,用于管理或操作数组(比如排序和搜索)
-
toString—返回数组的字符串形式
//int[] arr = { 1,2,3 }; //System.out.println(Arrays.toString(arr)); //输出[1,2,3]
-
sort 排序(自然排序和定制排序)
Integer arr[] = {1,-1,7,0,89,3};
//可以自己写冒泡,也可以用Arrays的sort(),从小到大
//因为数组是引用类型,所以通过sort排序后会直接影响到实参
//sort方法重载,也可以通过传入一个接口Comparator实现定制排序
//调用定制排序时,传入两个参数,一是排序的数组,二是实现了Comparator接口的匿名内部类,要求实现compare方法
//这里体现了接口编程的方式,在binarySort方法底层,会通过匿名内部类的compare方法来决定排序的顺序
Arrays.sort(arr, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
return i2 - i1;
}
});
//源码分析:
/*
(1) Arrays.sort(arr, new Comparator()
(2) 最终到 TimSort 类的 private static <T> void binarySort(T[] a, int lo, int hi, int start,
Comparator<? super T> c)()
(3) 执行到 binarySort 方法的代码, 会根据动态绑定机制 c.compare()执行我们传入的匿名内部类的 compare ()
// while (left < right) {
// int mid = (left + right) >>> 1;
// if (c.compare(pivot, a[mid]) < 0)
// right = mid;
// else
// left = mid + 1;
// }
//(4) new Comparator() {
// @Override
// public int compare(Object o1, Object o2) {
// Integer i1 = (Integer) o1;
// Integer i2 = (Integer) o2;
// return i2 - i1;
// }
// }
//(5) public int compare(Object o1, Object o2) 返回的值>0 还是 <0会影响整个排序结果, 这就充分体现了 接口编程+动态绑定+匿名内部类的综合使用.将来的底层框架和源码的使用方式, 会非常常见
*/
- binarySearch — 通过二分搜索法进行查找,要求必须排好序
int index = Arrays.binarySearch(arr,3);
/*
1、使用binarySearch通过二分搜索法进行查找,要求必须有序,无序不能用
2、如果数组中不存在该元素,返回应插入的位置+1的相反数,存在返回索引
*/
- copyOf 数组元素的复制
Integer[] newArr = Arrays.copyOf(arr,arr.length);
/*
1. 从 arr 数组中, 拷贝 arr.length 个元素到 newArr 数组中
2. 如果拷贝的长度 > arr.length 就在新数组的后面 增加 null
3. 如果拷贝长度 < 0 就抛出异常 NegativeArraySizeException
4. 该方法的底层使用的是 System.arraycopy()
*/
- fill数组元素的填充
lnteger[]num = new Integer[]{9,3,23};
Arrays.fill(num, 99);
//使用 99 去填充 num 数组, 可以理解成是替换原来所有的元素
//num 变成 99 99 99
- equals比较两个数组元素内容是否完全一致,不是地址
boolean equals = Arrays.equals(arr,arr2);
//1. 如果 arr 和 arr2 数组的元素一样, 则方法 true;
//2. 如果不是完全一样, 就返回 false
- asList 将一组值,转换成list
List<Integer> asList = Arrays.asList(2,3,4,5,6,1);
System.out.println("asList=" + asList);
//1. asList 方法, 会将 (2,3,4,5,6,1)数据转成一个 List 集合
//2. 返回的 asList 编译类型 List(接口)
//3. asList 运行类型 java.util.Arrays#ArrayList, 是 Arrays 类的
// 静态内部类 private static class ArrayList<E> extends AbstractList<E>
// implements RandomAccess, java.io.Serializable
作业
import java.util.Arrays;
import java.util.Comparator;
/**
* @author CUI
* @version 1.0
*/
public class ArraysExercise {
public static void main(String[] args) {
Book[] books = new Book[4];
books[0] = new Book("红楼梦", 100);
books[1] = new Book("金瓶梅", 90);
books[2] = new Book("青年文摘", 5);
books[3] = new Book("java从入门到放弃", 300);
// Book temp = null;
// for (int i = 0; i < 4; i++) {
// for (int j = 0; j < books.length - i - 1; j++) {
// if(books[j + 1].getPrice() > books[j].getPrice()){
// temp = books[j + 1];
// books[j + 1] = books[j];
// books[j] = temp;
// }
// }
// }
// for(Book b : books){
// System.out.println(b.getName()+ " " + b.getPrice());
// }
//
// System.out.println("==========================");
//
// for (int i = 0; i < 4; i++) {
// for (int j = 0; j < books.length - i - 1; j++) {
// if(books[j + 1].getName().length() > books[j].getName().length()){
// temp = books[j + 1];
// books[j + 1] = books[j];
// books[j] = temp;
// }
// }
// }
//
// for(Book b : books){
// System.out.println(b.getName()+ " " + b.getPrice());
// }
Arrays.sort(books, new Comparator<Book>() {
@Override
public int compare(Book o1, Book o2) {
double difference = o1.getPrice() - o2.getPrice();
if (difference > 0) {
return -1;
} else if (difference < 0) {
return 1;
} else {
return 0;
}
}
});
for (Book b : books) {
System.out.println(b.getName() + " " + b.getPrice());
}
}
}
class Book {
private String name;
private double price;
public Book(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}