1、java.lang包下的类在使用的时候是不需要导包的
2、sc.next()—遇到空格和tab键输入会有问题; 和 sc.nextLine()—遇到\r\n就会停止
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个整数");
int num = sc.nextInt(); // \r\n
System.out.println("请输入一个字符串");
String s = sc.nextLine();// 遇到上个步骤留下来的\r\n就直接结束了
sc.close();
建议都使用nextLine来作为输入
3、如果打印一个对象的引用, 结果不是全类名 + 16进制地址值的话, 说明该对象就重写了toString方法
4、==号,基本数据类型比较的是值是否相等,引用数据类型比较的是地址值是否相等
5、equals方法只能比较引用数据类型是否相等,因为是一个方法,就必须用对象来调用
@Override
public boolean equals(Object obj) {
if (this == obj) // 如果当前对象和传入对象的地址值相同, 直接返回true
return true;
if (obj == null) // 如果传入的对象为null, 那就说明当前对象有值, 传入对象没值, 没有可比性了, 返回false
return false;
if (getClass() != obj.getClass()) // 如果当前对象的字节码和传入对象的字节码不一致, 说明类型不一样, 没有可比性, 返回false(省略this.getClass())
return false;
Person other = (Person) obj; // 向下转型,不转拿不到属性值
if (age != other.age) // 年龄不同, 直接返回false(省略this.age)
return false;
if (name == null) {
if (other.name != null) // 当前对象的name如果为null, 传入对象的name不是null, 直接返回false
return false;
} else if (!name.equals(other.name)) // 如果姓名不一样, 返回false;
return false;
------------------------------------
String name = "zhangsan";
String name1 = "zhangsan";
System.out.println(name==name1);//true
int [] a = {1,2,3};
int [] b = {1,2,3};
System.out.println(a==b);//false
6、挺好的程序,看看
package com.heima.test;
import java.util.Scanner;
public class Test1Student {
/*
* 需求: 键盘录入两个学生信息, 比较两个学生的属性值是否相同, 如果相同则打印学生信息, 如果不相同给出提示
*
* 学生信息: 姓名, 年龄
*/
static Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
Student stu1 = getStu();
Student stu2 = getStu();
if(stu1.equals(stu2)){
System.out.println(stu1);
}else{
System.out.println("您输入的两个学生信息不相同");
}
}
public static Student getStu(){
System.out.println("请输入学生姓名:");
String name = sc.next();
System.out.println("请输入学生年龄:");
int age = sc.nextInt();
Student s = new Student(name,age); //调用了Studeet类
return s; //返回Student类对象引用
}
}
class Student {
private String name;
private int age;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
7、字符串是不可被改变的,本身就是一个对象,并没有像其他类的set方法来对其进行改变;字符串底层是一个字符数组
8、String构造方法:
在java1.8之后,就把String的char类型转换为了byte类型!!!
private final char value[];//jdk1.8
private final byte value[];//jdk1.9
- String(String original): 把字符串数据封装成字符串对象
- String(char[] value) : 把字符数组的数据封装成字符串对象
- String(char[] value, int index, int count): 把字符数组中的一部分数据封装成字符串对象
9、字符串常量池(在方法区中),jdk1.8版本之后, 字符串常量池从方法区移动到了堆内存
字符串常量池的概念:
* 当我们在使用双引号创建字符串对象的时候, 首先会检查该字符串在常量池中是否存在
*
* 如果不存在, 则创建
* 如果存在, 不再重复创建, 而是直接引用原有的字符串地址
*/
public static void main(String[] args) {
String s1 = "123";
String s2 = new String("123"); //s2会指向堆内存中的123,不是常量池中的,此步骤创建了两个对象,字符串常量池和堆内存中都有一个
String s3 = "123";
System.out.println(s1 == s2);//false
System.out.println(s1 == s3);//true
}
}
public class TestString {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "a" + "b" + "c"; // Java有常量优化机制, 在编译生成字节码的时候, 就会将该代码变成 String s2 = "abc";
System.out.println(s1 == s2); // true !!!!!!!!!
}
public static void method3() {
String s1 = "abc"; //当字符串之间使用+号进行串联的时候,底层都会自动创建一个字符串缓冲区StringBuilder,底层调用append方法完成字符串的拼接
String s2 = "ab";
String s3 = s2 + "c";
System.out.println(s1 == s3); // false
}
public static void method2() {
String s1 = "123";
String s2 = new String("123");
System.out.println(s1 == s2); // false s1记录的是常量池地址, s2记录的是堆内存地址
// s2中的字符串数据, 是常量池中的副本
}
public static void method1() {
String s1 = "123";
String s2 = "123";
System.out.println(s1 == s2); // true 因为s1和s2都是指向常量池中的地址
}
}
10、不错的程序
/*
* 需求: 模拟登录,给三次机会,并提示还有几次
* 1. 创建键盘录入对象, 准备接受数据
* 2. 调用两次next方法, 接受字符串类型的用户名和密码
* 3. 假设用户名和密码都是"admin", 让键盘录入的用户名和密码进行比较
*/
public static void main(String[] args) {
// 1. 创建键盘录入对象, 准备接受数据
Scanner sc = new Scanner(System.in);
for(int i = 1; i <= 3; i++){
// 2. 调用两次next方法, 接受字符串类型的用户名和密码
System.out.println("请输入用户名:");
String userName = sc.next();
System.out.println("请输入密码:");
String passWord = sc.next();
// 3. 假设用户名和密码都是"admin", 让键盘录入的用户名和密码进行比较
if("admin".equals(userName) && "admin".equals(passWord)){ //!!!!
System.out.println("登陆成功");
// 4. 如果登陆成功, 结束循环
break;
}else{
// 5. 如果循环到达了最后一次, 给出特殊的提示
if(i == 3){
System.out.println("明儿再来");
}else{
System.out.println("登陆失败, 您还有" + (3-i) + "次机会");
}
}
}
}
}
11、获取字符串中的每一个字符
第一种遍历方式:
* int length():获取字符串的长度,其实也就是字符个数
* char charAt(int index):获取指定索引处的字符
* // StringIndexOutOfBoundsException --> 字符串索引越界异常
for(int i = 0; i < s.length(); i++){
System.out.println(s.charAt(i));//根绝i值来获取相应索引处的字符值
}
第二种遍历方式:
* char[] toChatArray() : 将字符串拆分成字符数组
char[] cArr = s.toCharArray();
for (int i = 0; i < cArr.length; i++) { //获得字符数组
System.out.println(cArr[i]);
}
12、StringBuilder会提高效率
String是一个不可改变的字符序列
StringBuilder是一个可以改变的字符序列(初始容量是16个字符)
字符串的拼接: 每一次用+号串联的时候, 底层都会重新创建一个StringBuilder, 然后再通过append方法完成拼接, 最后通过toString方法转换成字符串
---这个步骤, 是每一次相加都会进行的步骤--- 所以说非常消耗内存
StringBuilder的拼接: 单独在堆内存中创建一块空间, 所有的数据拼接, 都在这一块空间内进行. 如果想转成字符串, 可以在拼接结束后, 手动调用toString方法进行转换.
public class Demo4_StringBuilder {
/*
* StringBuilder : 是一个可变的字符序列
*
* StringBuilder append(String str) : 返回该对象自己本身
*/
public static void main(String[] args) {
// 1. 创建一个空的字符串缓冲区(区域, 容器)
StringBuilder sb = new StringBuilder();
// 2. 调用append方法添加数据
StringBuilder sb1 = sb.append("aaa");
StringBuilder sb2 = sb.append("bbb");
System.out.println(sb1 == sb2); // true,不会重新开辟空间,返回的是自己!!!
// 链式编程: 如果一个方法的返回值是一个对象, 对象就可以继续向下调用方法
sb.append("红色").append("蓝色").append("绿色");
System.out.println(sb.reverse()); //直接反转
}
}
13、StringBuilder和String的相互转换
Scanner sc = new Scanner(System.in);
System.out.println("请输入:");
String s = sc.nextLine();
StringBuilder sb = new StringBuilder(s); //将字符串转为StringBuilder
System.out.println(sb.reverse()); //通过StringBuilder来进行字符串的反转,因为String里没有这个方法
sb.toString; //就可以转换为String了
public class Demo5_StringBuilder {
/*
* String和StringBuilder的相互转换
*
* 思路: 为什么两者需要相互转换呢?
*
* 有些时候, 我们需要用到的方法, String里面没有, 但StringBuilder里面有, 就可以进行转换.
*
* 1. String - StringBuilder
*
* 根据StringBuilder的构造方法即可
*
* StringBuilder(String s)
*
* 2. StringBuilder - String
*
* 调用StringBuilder的toString方法
*
* 需求: 键盘录入一个字符串, 判断该字符串是否是对称字符串
*
* 123321 123321
* 111 111
* 123123
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个对称字符串:");
String src = sc.next();
// 将字符串转换为StringBuilder目的就是为了调用反转的方法
StringBuilder sb = new StringBuilder(src);
// 将反转后的数据跟源字符串进行比对
String dest = sb.reverse().toString();
if(src.equals(dest)){
System.out.println("是对称字符串");
}else{
System.out.println("不是对称字符串");
}
}
}
14、StringBuilder是jdk1.5版本的,StringBuffer是jdk1.0版本的。StringBuilder是线程不安全的,StringBuffer是线程安全的。
15、总结
1. Object
* toString : 用于展示数据更加方便
1. 打印对象引用的时候, println默认会调用该对象的toString方法
2. 推荐重写类的toString方法, 让该方法打印对象的属性值
Person p = new Person("张三",23);
System.out.println(p);
alt + shift + s + s
* equals : 用于对象之间比较属性的
1. 如果没有重写Object类的equals方法, 默认比较的也是地址值
2. 推荐重写Object类的equals方法, 让对象的比较, 根据内容进行比较
alt + shift + s + h
2. String
特点:
1. String是一个不可改变的字符序列
2. 所有双引号都是String这个类的对象
思路:
char[]数组和String之间是可以相互转换的
字符数组 - 字符串 char[] cArr = {'a','b','c'};
String s = new String(cArr);
字符串 - 字符数组 String s = "abc";
char[] cArr = s.toCharArray();
构造方法:
1. String(String s); // 将传入的字符串, 封装为字符串对象, 但是这种方式会创建两个字符串对象
2. String(char[] value); // 将传入的字符数组, 转换为字符串
3. String(char[] value, int index, int count);
// 将字符数组的一部分转换为字符串
成员方法:
1. int length() : 返回字符串中字符出现的个数
2. char[] toCharArray() : 将一个字符串拆分成字符数组
3. char charAt(int index) : 根据索引获取字符
4. boolean equals() : 比较两个字符串的内容是否相同, 区分大小写
5. boolean equalsIgnoreCase() : 比较两个字符串的内容是否相同, 忽略大小写
3. StringBuilder
1. StirngBuilder是可以改变的字符序列
2. StringBuilder是字符串的缓冲区, 可以对于字符串的操作, 提高效率
构造方法:
StringBuilder() : 创建一个空的字符串缓冲区, 里面不带任何任务
StringBuilder(String s) : 创建一个字符串缓冲区, 里面带有传入的字符串数据
成员方法:
StringBuilder(自己) append(任意类型);
append方法支持链式编程.
StringBuilder reverse() : 对整个缓冲区的内容, 进行反转.
int length() : 获取缓冲区中的字符的个数
String toString() : 将字符串缓冲区, 转换为String字符串
重点:
String - StringBuilder的相互转换
String - StringBuilder 可以通过StringBuilder的构造方法
StringBuilder sb = new StringBuilder("abc");
StringBuilder - String
可以通过toString方法,sb.toString();