目录
1.jdk中的常用接口
2.Clone接口
3.浅拷贝
4.深拷贝
实现方式:1.递归
5.序列化与反序列化
5.1包装类:将基本数据类型封装使其可以用object类接收
5.2拆箱装箱
6.String类型
字符串建立
6.2字符串比较
6.3字符串对象的大小比较,String类也实现了CompareTo方法
6.3字符串的转变
6.4字符串常用方法
7.笔试面试
1.字符串常量池
2.字符串的不可变性
8.字符串修改
1.StringBulider 常用方法
1. append() 在后面加
2. insert() 在指定位置添加
3. deleteCharAt() 删除指定位置字符
4. delete() 删除指定范围字符串(左闭右开)
5. setCharAt() 修改指定位置字符为新的字符
6. replase() 修改指定范围字符串为新的字符串
7. reverse() 将字符串逆序
9.动态数组
1.jdk中的常用接口
Java.long.CompareTo接口
实现这个接口的类,必须重写CompareTo方法
基本数据类型大小关系确定,
以Student类为例
public class Student implements Comparable{
public String name;
public int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", score=" + score +
'}';
}
@Override
public int compareTo(Object o) {
if(this == o){
return 0;
}else if(!(this instanceof Student)){
return -1;
}else {
Student student = (Student) o;
return -(this.score - student.score);
}
}
}
public class Test01{
public static void main(String[] args) {
int [] arr = {1,2,5,7,34,657,23};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
Student [] student = new Student[3];
student[0] = new Student("小金",80);
student[1] = new Student("小锦鲤",70);
student[2] = new Student("大金",78);
Arrays.sort(student);
System.out.println(Arrays.toString(student));
}
}
2.Clone接口
在类的定义上实现Clone able接口:打标记,JVM只会将Cloneable接口的子类赋予其可以拷贝的能力
在类中覆写Object类中的Clone方法:具体实现以Animal为例
public class Animal implements Cloneable{
private String name;
private int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
@Override
protected Animal clone() throws CloneNotSupportedException {
return (Animal) super.clone();
}
@Override
public String toString() {
return "Animal{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Test02 {
public static void main(String[] args) throws CloneNotSupportedException {
Animal animal = new Animal("小狗",4);
Animal animal2 = animal.clone();
System.out.println(animal2);
System.out.println(animal);
System.out.println(animal == animal2);
}
3.浅拷贝
当前类中若有其他类的引用,浅拷贝不会拷贝其引用,只是将属性复制一份而已
public class Test02 {
public static void main(String[] args) throws CloneNotSupportedException {
Animal animal = new Animal("小狗",4,"黑");
Animal animal2 = animal.clone();
System.out.println(animal2);
System.out.println(animal);
System.out.println(animal.dog == animal2.dog);
animal2.dog.color = "白";
System.out.println(animal.dog.color);
}
4.深拷贝
当前类中的其他引用也会拷贝一份
实现方式:1.递归
public class Test02 {
public static void main(String[] args) throws CloneNotSupportedException {
Animal animal = new Animal("小狗",4,"黑");
Animal animal2 = animal.clone();
animal2.dog = animal.dog.clone();
System.out.println(animal2);
System.out.println(animal);
System.out.println(animal.dog == animal2.dog);
animal2.dog.color = "白";
System.out.println(animal.dog.color);
}
}
5.序列化与反序列化
将任意对象转为字符串的操作叫序列化,
根据序列化反序列化产生的对象一定都是深拷贝对象
object类可以接受一切引用数据类型的对象
5.1包装类:将基本数据类型封装使其可以用object类接收
jdk中的包装类
public class Test01 {
public static void main(String[] args) {
Byte bb = new Byte("1");
Short s = new Short("13");
Integer a = new Integer(10);
Long l = new Long(23);
Object j = a;
Float f = new Float(12.1);
Double d = new Double(11.1);
Character c = new Character('w');
Boolean b = new Boolean(true);
}
}
5.2拆箱装箱
将基本类型保存到对应的包装类之中叫装箱
将包装类对象还原为具体的基本类型为拆箱
valueof() Intvalue()
包装类的对象进行数学运算时,会自动拆装箱
public class Test01 {
public static void main(String[] args) {
Integer i1 = 20;
Integer i = i1+10;
System.out.println(i);
}
}
在类中定义的属性,推荐使用包装类,在方法中的局部变量,可以使用基本类型
基本数据类型的默认值是一把双刃剑
判断银行卡是否开卡
int count = 0;
for (int i = 0; i < bankCards.length; i++) {
if(bankCards[i].getBalance() == null){
count++;
}
}
System.out.println(count);
以整数包装类为例
整数包装类有缓存-128到127之间整数数值,当第一次包装类对象数字再其之间时,产生新的对象,第二次出现时,直接覆用已有对象,但是在缓存之外的每次包装时都产生新对象
public class Test03 {
public static void main(String[] args) {
Integer b = 127;
Integer d = 127;
System.out.println(b == d);
Integer b1 = 128;
Integer d1 = 128;
System.out.println(b1 == d1);
}
}
6.String类型
字符串建立
public class StringBuild {
public static void main(String[] args) {
//推荐使用第一种
String str1 = "hello";
String str2 = new String("hello2");
char [] str = {'l','i'};
String str3 = String.valueOf(str);
System.out.println(str1+str2+str3);
}
}
6.2字符串比较
使用equals()方法
equalsIgnoreCase()方法比较不区分大小写
public class Test04 {
public static void main(String[] args) {
String str1 = "HELLO";
String str2 = "hello";
System.out.println(str1.equals(str2));
System.out.println(str1.equalsIgnoreCase(str2));
}
}
6.3字符串对象的大小比较,String类也实现了CompareTo方法
字符串大小比较返回值:1.先按照字典序比较,若不相等,则返回这两个字符的大小差值
2.两个字符串abs absdk 返回字符串长度差值2
3.两个字符串完全相等,返回0
public class Test04 {
public static void main(String[] args) {
String str1 = "HELLO";
String str2 = "H";
System.out.println(str1.compareTo(str2));
}
}
CompareToIgnoreCase()与CompareTo完全一致,只是不区分大小写
public class Test04 {
public static void main(String[] args) {
String str1 = "HELLO";
String str2 = "hello";
System.out.println(str1.compareTo(str2));
System.out.println(str1.equalsIgnoreCase(str2));
}
}
6.3字符串的转变
其他任意类型转换为字符串,调用valueof方法
将字符串对象还原为数值,调用parse方法
public class Test04 {
public static void main(String[] args) {
int age = 100;
String str = String.valueOf(age);
System.out.println(str);
String str3 = str;
age = Integer.parseInt(str3);
int i = age;
System.out.println(i);
}
}
6.4字符串常用方法
1.查找指定位置的字符charAt(int index),越界抛出异常
2.字符串长度length()
3.indexOf() :从字符串的开始位置中查找指定字符或字符串,
若存在,返回第一次出现的下标,不存在返回-1
lastIndexOf() : 从字符串的末尾位置中查找指定字符或字符串
4.boolean contains(传入字符串):查询当前字符串对象中是否包含指定内容
public class Test05 {
public static void main(String[] args) {
String str1 = "HElloHelloXiaojinli";
System.out.println(str1.charAt(7));
System.out.println(str1.length());
System.out.println(str1.indexOf('X'));
System.out.println(str1.indexOf("Xiao"));
System.out.println(str1.contains("X"));
}
}
5.判断一个字符串是否由纯数字组成
public static boolean judge(String str){
for (int j = 0; j < str.length(); j++) {
if(str.charAt(j) < '0' || str.charAt(j) > '9' ){
return false;
}
}
return true;
}
6.字符串替换,指定一个新的字符替换已有的字符
replaseAll() 全部替换
replaseFirst() 只替换第一个
String str2 = "dddddd";
System.out.println(str2.replaceAll("d","a"));
System.out.println(str2.replaceFirst("d","a"));
7.字符串拆分,按照指定分隔符拆分为数组
String str3 = "Hello ni hao ya xiao jin li";
String [] st = str3.split(" ");
System.out.println(Arrays.toString(st));
String [] st2 = str3.split("i",5);
System.out.println(Arrays.toString(st2));
8.双层拆分
split()方法 ,拆分时某些特殊分隔符需要进行转义处理 \\.表示其单纯的用.作为分隔符而已
String str4 = "12!3.45!6.7!89";
String [] str5 = str4.split("\\.");
System.out.println(Arrays.toString(str5));
for (int i = 0; i < str5.length; i++) {
String [] str6 = str5[i].split("\\!");
System.out.println(str6[0] +" " + str6[1]);
}
9.字符串截取,subString() 左闭右开
str3 = "Hello ni hao ya xiao jin li";
System.out.println(str3.substring(5,8));
10.trim()将字符串中左右空格去掉,保留中间空格
System.out.println(str3.trim());
11.大小写转换
String str7 = "HELLO";
System.out.println(str7.toUpperCase());
System.out.println(str7.toLowerCase());
12.首字母大写
str7 = "hello";
System.out.println(str7.substring(0,1).toUpperCase()+str7.substring(1));
7.笔试面试
1.字符串常量池
当字符串对象采用直接赋值法,字符串对象第一次产生时,就会产生该字符串对象,置入常量池中,当直接赋值法产生对象时,常量池中已经包含了该值的对象,则会直接复用常量池中的对象
String str1 = "hello";
String str2 = "hello";
String str3 = "hello";
String str4 = new String("hello");
System.out.println(str1 == str2);
System.out.println(str1 == str3);
System.out.println(str1 == str4);
2. 将当前字符串对象尝试置入常量池中,
1.若常量池中已存在,返回原有对象地址
2.若不存在,返回存储地址
public native String intern();
char [] ch = new char[]{'a','b','c'};
//堆上的字符串
String s1 = new String(ch);
s1.intern();
String s2 = "abc";
System.out.println(s1 == s2);
2.字符串的不可变性
String对象一旦产生,字符串对象中保存的值不可改变,改变的都是其引用
原因:private final char value[] ;
final修饰的数组value的引用不能变,它只能指向这个数组,但数组内的值可以改变
value数组是真正存储数据的数组,因其被private修饰,且并没有对外提供get和set方法,所以无法修改
public class Test07 {
public static void main(String[] args) {
String s1 = "hello";
char [] ch = {'h','e','l','l','o'};
change(s1,ch);
System.out.println(s1);
System.out.println(ch);
}
public static void change(String s,char[] ch){
s = "Hello";
ch[0] = 'H';
}
}
【原因分析】
方法Change中产生的String s字符串并未在常量池中出现过,所以只是产生了一个新的字符串,而并非修改了主方法中的字符串
8.字符串修改
1.当需要字符串的修改时,需要用到Jdk中提供的两个类
由于字符串的不可变性,
String Buffer是线程安全的类,性能较差,一般用在多线程并发修改内容
StringBulider是线程不安全的类,性能较高,能满足大部分场景
当str使用+符号时,javac默认将其转为Stringbulider对象处理
public class Test01 {
public static void main(String[] args) {
String str1 = "xiao";
StringBuilder sb = new StringBuilder(str1);
sb.append(str1);
String strResult = sb.toString();
}
}
1.StringBulider 常用方法
1. append() 在后面加
2. insert() 在指定位置添加
StringBuilder sb1 = new StringBuilder("Hello");
sb1.append("jinli");
System.out.println(sb1);
//在指定位置插入
sb1.insert(0,"nihao");
System.out.println(sb1);
3. deleteCharAt() 删除指定位置字符
4. delete() 删除指定范围字符串(左闭右开)
sb1.deleteCharAt(0);
System.out.println(sb1);
sb1.delete(0,1);
System.out.println(sb1);
5. setCharAt() 修改指定位置字符为新的字符
6. replase() 修改指定范围字符串为新的字符串
System.out.println(sb1);
sb1.setCharAt(0,'H');
System.out.println(sb1);
sb1.replace(0,3,"nihao");
System.out.println(sb1);
7. reverse() 将字符串逆序
sb1.reverse();
System.out.println(sb1);
9.动态数组
JDK中的动态数组List接口(线性表)
1.ArrayList 动态数组实现:
存放基本类型数据时使用其包装类
public interface IOperation {
public static void main(String[] args) {
//实现一个存放整形数据的动态数组
List<Integer> list = new ArrayList<>();
}
}
2.add() 向List中添加元素(默认在最后添加)
list.add(10);
list.add(20);
list.add(30);
System.out.println(list);
3.remove() 删除指定下标元素
list.remove(0);
System.out.println(list);
4.set() 修改指定下标的元素
list.set(0,100);
System.out.println(list);
5.get() 获取指定下标的元素
boolean contains() 查找某个元素是否在数组中
System.out.println(list.get(0));
System.out.println(list.contains(100));