这里有静态语句块和实例语句块,StringBuffer,StringBuilder,数组,Arrays工具类,集合,List,Set
我本身也在复习,一遍复习一边写的,现在又在工作,每天晚上才有一点时间复习。
关于静态语句块和实例语句块有点忘记了,刚才回顾了一下。
静态语句块就是static{},在类加载的时候执行,而且只执行一次。
实例语句块就是{},在构造方法执行前执行,也就是在new这个对象的时候会先执行实例语句块的代码,按顺序执行。想试试的话,new两次Bean对象就知道了。
public class Bean {
static {
System.out.println("Bean静态语句块,类加载时执行,只执行一次");
}
{
System.out.println("Bean实例语句块,new对象的时候执行,1");
}
{
System.out.println("Bean实例语句块,new对象的时候执行,2");
}
public Bean() {
System.out.println("Bean,构造函数");
}
}
再说一下String,因为这个只要创建了,就不能修改,所以如果需要频繁创建或者拼接的时候最好不要用了。
用StringBuffer,StringBuffer内部采用的是byte[],用这个对象的append()方法拼接字符串,大量减少字符串常量池的内存使用情况,而且StringBuffer是线程安全的,因为这个对象里面的方法基本都加上了synchronized修饰,synchronized是一个锁,后面复习到多线程的时候在仔细写一下,这里挖个坑,留着以后填。
还有一个类是StringBuilder,和StringBuffer使用是一样的,而且这个比StringBuffer速度快,但是有个缺点,如果在多线程中使用,就不安全了,以为这个类的方法都没有synchronized修饰。
说一下啥时候用StringBuilder把,比较常见的是后台代码的拼接sql语句的时候,经常一大堆判断条件,需要追加的条件太多,这时候最好用StringBuffe。
还有一个常用类,就是枚举enum,枚举也能在switch里面使用,但是低版本就就不支持了。首先定义一个枚举:
//定义一个枚举,
//注意枚举里面不需要数据类型,枚举就相当于你自定义个数据类型,
//只要你别用关键字,随便定义,用逗号隔开就行了,你想定义几个就定义几个
public enum EnumTest {
first,one,two,three
}
怎么配合switch进行判断呢,看下面代码:
public class Test{
public static void main(String[] args) {
enumMethod(EnumTest.first);
}
//根据枚举判断
public static void enumMethod(EnumTest enumTest){
switch (enumTest){
case first:
//do something
System.out.println(enumTest);
break;
case one:
System.out.println(enumTest);
break;
case two:
System.out.println(enumTest);
break;
case three:
System.out.println(enumTest);
break;
default:
break;
}
}
}
该看看容器了,Array数组,数组就相当于固定的大盒子,里面有一个一个的小盒子,每次创建一个数组,都是一个固定的盒子。记住数组创建了,能存放的数据量就固定了。如何定义一个数组,下面代码:
//四个int类型的数据,并直接赋值
int[] arrayInt = new int[]{1,20,3,4};
//5个String类型的数据,并直接赋值
String[] arrayStr = {"aa","bb","cc","dd","edf"};
//这个就是能存十个char类型的数据,目前这个里面只是定义了大小,没有实际的数据
char[] arrChar = new char[10];
int arrIntLength = arrayInt.length;//4
int arrayStrLength = arrayStr.length;//5
int arrCharLength = arrChar.length;//10
上面的是一维数组,一维知道什么意思吧,就是一条线,一条线不够用的时候怎么办呢,就有了二维数组。怎么写,看下面代码:
int[][] arrInt = {{1,10},{3,5}};
for (int i = 0; i < arrInt.length; i++) {
for (int j = 0; j < arrInt[i].length; j++) {
System.out.println("arrInt["+i+"]:"+arrInt[i]+"--arrInt["+i+"]["+j+"]:"+arrInt[i][j]);
}
}
/*这是我的执行结果,[I@1540e19d这是地址值,其他人运行这个值就不一样了
arrInt[0]:[I@1540e19d--arrInt[0][0]:1
arrInt[0]:[I@1540e19d--arrInt[0][1]:10
arrInt[1]:[I@677327b6--arrInt[1][0]:3
arrInt[1]:[I@677327b6--arrInt[1][1]:5*/
如果自己写排序是不是挺费事的,所以java开发者给咱们提供了一个强大的工具类Arrays,这个类里面的方法给用户用的,都是静态方法,直接类名点就可以直接使用了,不用new对象。简单说两个方法,一个是sort()方法,对数组进行排序,还有一个方法binarySearch(),采用二分法查找你想要的值所在的下标。二分法是一种算法,后面复习到的时候在详细写写,先挖个坑在这,以后填。
如果有固定不变的数据,就用数组就行了,定义并赋值,还是挺方便的,但是因为数组定义的时候就限定的容量,如果数据量不确定的时候,就太不方便了,所以java开发者很好心的出了一个叫做集合的类,集合是根据数据量动态申请内存空间的,而且还是两个集合类,一种是List,另一种是Set,这两个都是接口不能实例化。
首先说一下List,这个集合是有序可重复,有序的意思按照存入的顺序,从0~往后存,根据角标可以按照顺序取出来。List的常用实现类有两个,一个是ArrayList,一个是LinkedList。
ArrayList的底层采用的数组存储元素的,比较适合查询,不是和频繁增删。
LinkedList的底层是双向链表存储元素,比较适合增删,不适合查询。这里又要挖个坑了,链表数据结构以后再说。
还有一个Vector也是List的实现类,而且是线程安全的,但是效率比较低,目前用的人不太多,知道一下就行了。
Set这个集合,无序不可重复,它的常用实现类是HashSet。
SortedSet是Set的派生类,但是同样是接口,不过这个比较有意思,既然是Set的派生类,那么他也是不可重复的,但是SortedSet会根据元素的大小自动排序,这就和List的有序不一样了,它的实现类是TreeSet。
以上是一个一个的存储,还有一种是一对一对存储的,就是Map集合,是以键值对方式存储的,键(key)是不可重复的,值(value)是可重复的,Map是一个接口,不能实例,能实例的是它的子类,HashMap,这个集合是无序的。Map集合下还有一个SortedMap接口,实现了Map接口,具体的实现类是TreeMap集合,TreeMap集合是有序的集合。
上面这些集合都是平时比较常用的集合,能满足一般项目需求。