网站建设相关知识山西网络营销外包
2.3.3 引用数据类型
引用数据类型大致包括:类、 接口、 数组、 枚举、 注解、 字符串等
它和基本数据类型的最大区别就是:
- 基本数据类型是直接保存在栈中的
- 引用数据类型在栈中保存的是一个地址引用,这个地址指向的是其在堆内存中的实际位置。(栈中保存的是一个地址,而实际的内容是在堆中,通过地址去找它实际存放的位置)
1、String字符串
在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串,所以String是引用数据类型。Java语言中字符串必须包含在一个 " " 中。
字符串的创建:
两种创建方式:
1、String str1 = "name"; //直接定义,在常量池中
2、String str2 = new String("name"); //在常量池创建后,再在堆中创建对象
//new每次都会创建一个新的对象,而String直接创建的字符串如果值相同则每次指向的都是同一个对象
//String 类是不可改变的,所以你一旦创建了 String 对象,那它的值就无法改变了,
//重新赋值只是改变存储的数据地址
1和2两种创建方式的区别:两者都会去字符常量池中检查是否存在 "name",如果有则直接引用,没有则在常量池中创建(其实这个实例也是在堆中的,字符串常量池中是引用地址)但是2还会通过new在堆中创建一个同样内容的对象实例
String是最基本的实际类型吗?
不是,基本数据类型有:byte、short、int、long、float、double、Boolean、char8种
ava.lang.String类是final类型的,所以String不能继承和修改。String、StringBuffer、StringBuilder的区别
都是用于操作字符串,但是String类是final类型,内容不可改。StringBuffer、StringBuilder类可修改。String的更改是从新创建一个对象,再指向这个新的对象,所以大量操作时速度较慢。StringBuffer、StringBuilder可直接修改值。
StringBuilder的运行效率高,但是线程不安全。如果字符串变量在方法中定义,只能有一个线程访问的情况下使用
StringBuffer是线程安全的,在类里定义成员变量,且实例对象在多线程环境中使用,则用此类
常用的方法
1、字符串的拼接:用'+'来拼接多個字符串String a = "hello"; String b = "Java"; System.out.println(a+b); 結果:hello Java用'+'连接字符串和其他数据类型String a = "3+2="; int b = 5; System.out.println(a+b); 结果:3+2=5str1.concat(str2):会在str1后拼接str2String str1 = "拼接";String str2 = "一起";System.out.println(str1.concat(str2)); //结果:拼接一起System.out.println(str1); //结果:拼接System.out.println(str2); //结果:一起2、获取字符串长度:str.length();3、获取字符串中的字符:str.charAt(i); //i是字符串内每个字符的索引位置从0开始,length-1结束4、比较字符串不忽略字母大小写:str1.equals(str2);忽略字母大小写:str.equalsIgnoreCase(str2);5、获取某一字符的位置:查找指定字符第一次出现的位置:str.indexOf("指定的字符")从指定位置(int)开始查找指定字符第一次出现的位置:str.indexOf("指定的字符",int)查找指定字符最后一次出现的位置:str.lastIndexOf("指定的字符")从指定位置(int)开始往前查找指定字符第一次出现的位置:str.lastIndexOf("指定的字符",int);6、字符串的截取:从指定位置截取到最后:str.subString(int)从指定位置截取到指定位置:str.subString(int1,int2); 区间[int1,int2)7、去除空格:去除首位空格:str.trim()去除所有空格(将所有空格替换):str.replaceAll("//s","");8、替换字符串中指定的字符将所有符合指定的字符串都替换成新字符串:str.replaceAll("原字符串","新字符串") 可使用字符串格式将指定字符替换换成其他字符:str.replace('原字符','新字符') 替换单个字符将符合指定字符串的第一个替换成新字符串,后续的不变:str.replaceFrist("原字符串","新字符串");9、判断字符串的开头与结尾(返回的是布尔值):判断某字符串是否以**开头:str.startsWith("**")判断字符串从指定位置开始是否以**开头:str.startsWith("**",int)判断某字符串是否以**结尾:str.endsWith("**");10、字符串中大小写转换:大写变小写:str.toLowerCase()小写变大写:str.toUpperCase();11、分割字符串:以指定字符分割:str.split('分隔符')以指定字符分割指定次数:str.split('分隔符',int);12、判断是否为空字符串:str.isEmpty();13、字符串的格式化:String str = String.formart("",); //和格式化打印类似
+可以用来连接字符串,也可以进行运算,所以在使用时需要注意:
![]()
2、数组
数组是固定长度、存储相同数据类型的一种数据结构,在内存中的体现是一个连续的内存空间。有索引值,可通过索引快速快速查询、修改相应元素。

基本特点:
1、数组的长度定义后不可更改,数组是有界限的[0,length-1],所以在使用过程中经常会遇到数组下标越界的异常
2、一个数组的类型定义后不可改,内部保存的元素必须是相同的
3、数组可定义为任意数据类型类型
4、数组属于引用类型,存放在堆中,栈中的数据实际上保存的是对象在堆中的地址
5、数组的访问通过索引值

Arrays类:
位于 java.util 包中,主要包含了操纵数组的各种方法
常用的函数:
1、打印数组元素 toString、deepToStringArrays.toString(数组名); //一维数组Arrays.deepToString(数组名); //多维数组
2、数组元素升序排列:sortArrays.sort(数组名); //数值按大小排序,String类型数组按照字典顺序,数字、大写字母、小写字母汉字的顺序
3、填充值:fillArrays.fill(数组名,值); //用指定的值填充数组全部的元素Arrays.fill(数组名,start,end,值); //数组下标为[start,end)的元素全部填充为指定值
4、比较数组:equals Arrays.equals(数组1,数组2);
5、复制数组 copyOf、copyOfRangecopyOf(数组名,复制的长度); //超过要复制的数组长度时,整型用0,char用null,小于数组长度截取数组copyOfRange(数组,start,end); //[start,end)截取数组进行复制
6、数组查询 binarySearchbinarySearch(数组,值) //如果要搜索的值在数组内,则返回该值的索引,否则返回-1binarySearch(数组,start,end,值) //在[start,end)范围内搜索相应的值
冒泡排序:
最常用的数组排序算法之一,将数组元素总是将小数往前放,大数往后放。基本思想是对比相邻的元素值,按规律进行交换。
public class BubbleSort {public static void main(String[] args) {int arr[] = {26,15,29,66,99,88,36,77,111,1,6,8,8};for(int i=0;i < arr.length-1;i++) {//外层循环控制排序趟数boolean flag = false; //通过布尔值进行判断,可减少一定的循环次数for(int j=0; j< arr.length-i-1;j++) {//内层循环控制每一趟排序多少次// 把小的值交换到前面if (arr[j]>arr[j+1]) {int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;flag = true; //如果判断过,flag就为true}}if(!flag){break;}}System.out.println("最终排序结果:");for(int a = 0; a < arr.length;a++) {System.out.println(arr[a] + "\t");}}
}
3、 枚举
枚举类型是Java 5中新增特性的一部分,它既是一种类(class,内部可以有方法和属性)却又比类多了些特殊的约束,但是这些约束的存在也造就了枚举类型的简洁性、安全性以及便捷性。
-
使用的场景
-
需要定义一组常量的时候:一年4个季节、一年12个月份、一星期7天、男女性别、支付方式等等。
-
创建单例模式的时候,内部只有一个对象,最简单的单例模式创建的方式
-
-
使用规则
- 不能被继承
- 不能被单独的new创建对象
- 枚举成员是用
,
隔开的。
在定义枚举类型时我们使用的关键字是enum,enum 定义的枚举类默认继承了 java.lang.Enum 类,并实现了 java.lang.Serializable 和 java.lang.Comparable 两个接口。有以下方法:
- values() 返回枚举类中所有的值。
- ordinal()方法可以找到每个枚举常量的索引,就像数组索引一样。
- valueOf()方法返回指定字符串值的枚举常量。
//枚举类型,使用关键字enum,定义周一到周日的常量
public enum Week {//不使用枚举需要定义常量// private final static String MONDAY = "星期一";.......MONDAY("星期一"), TUESDAY("星期二"), WEDNESDAY("星期三"),THURSDAY("星期四"), FRIDAY("星期五"), SATURDAY("星六"),SUNDAY("星期天");//枚举可以作为一个类,添加属性和方法Week(String name) {this.name = name;}private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}
public static void main(String[] args) {Week week1 = Week.FRIDAY;//在switch中使用switch (week1){case MONDAY: case TUESDAY: case WEDNESDAY:case THURSDAY: case FRIDAY: case SATURDAY:case SUNDAY:System.out.println(week1.getName());break;default:System.out.println("错误!!");}System.out.println("-----------分割线-------------");//迭代for (Week week2:Week.values()) {System.out.println(week2.getName());}System.out.println("-----------分割线-------------");//valueOf 通过指定字符串值返回枚举常量。Week week3 = Week.valueOf("MONDAY");System.out.println(week3.getName());System.out.println("-----------分割线-------------");//ordinal返回索引位置Week week = Week.FRIDAY;int ordinal = week.ordinal();System.out.println(ordinal);}
