文章目录
5)数字与字符串
装箱拆箱
封装类:所有的基本类型,都有对应的类类型,比如int对应的类是Integer,这种类就叫做封装类
Number类:数字封装类有Byte,Short,Integer,Long,Float,Double,这些类都是抽象类Number的子类
基本类型转封装类,Integer it = new Integer(5);
封装类转基本类型,int i = it.intValue();
自动装箱,不需要调用构造方法,通过=符号自动把基本类型转换为类类型就叫装箱,Integer it = 5;
自动拆箱,不需要调用Integer的intValue方法,通过=就自动转换成int类型,就叫拆箱,int i = it;
字符串转换
数字转字符串:
方法1: 使用String类的静态方法valueOf,String str = String.valueOf(5)
valueOf的参数可以是很多基本类型,也可以是字符数组
方法2: 先把基本类型装箱为对象,然后调用对象的toString,String str = it.toString()
字符串转数字:
调用Integer的静态方法parseInt,int i= Integer.parseInt(str)
数学方法
四舍五入:Math.round(0.45)
随机浮点数(0-1,取不到1):Math.random()
随机整数(0-10,取不到10):(int)( Math.random()*10)
开方:Math.sqrt(9)
次方(2的4次方):Math.pow(2,4)
常数π :Math.PI
自然常数:Math.E
字符
char对应的封装类
char c1 = 'a';
Character c = c1; //自动装箱
c1 = c;//自动拆箱
Character常见方法
System.out.println(Character.isLetter('a'));//判断是否为字母
System.out.println(Character.isDigit('a')); //判断是否为数字
System.out.println(Character.isWhitespace(' ')); //是否是空白
System.out.println(Character.isUpperCase('a')); //是否是大写
System.out.println(Character.isLowerCase('a')); //是否是小写
System.out.println(Character.toUpperCase('a')); //转换为大写
System.out.println(Character.toLowerCase('A')); //转换为小写
String a = 'a'; //不能够直接把一个字符转换成字符串
String a2 = Character.toString('a'); //转换为字符串
常见转义字符
\t是制表符,代表让其后面的字符对齐到下一个制表位,不仅仅代表光标后移8个字符(idea控制台移动4个字符,可以设置为8个)
System.out.println("换行:\n");
System.out.println("制表符:\t");
System.out.println("退格:\b");
System.out.println("回车:\r");
System.out.println("反斜杠:\\");
System.out.println("单引号:\'");
System.out.println("双引号:\"");
字符串
创建字符串
字符串即字符的组合,在Java中,字符串是一个类,所以我们见到的字符串都是对象
常见创建字符串手段:
char[] c1 = new char[]{'我','是','中','国','人'};
String str = "你好"; //每当有一个字面值出现的时候,虚拟机就会创建一个字符串
String str1 = new String("我是new出来的"); //调用String的构造方法创建一个字符串对象
String str2 = new String(c1); //调用String的构造方法创建一个字符串对象
String str3 = str + str1; //通过+加号进行字符串拼接也会创建新的字符串对象
System.out.format("%s,%s,%s,%s",str,str1,str2,str3);
String 被修饰为final,所以是不能被继承的
一旦创建好一个字符串,里面的内容永远不能改变,String 的表现就像是一个常量
length方法返回当前字符串的长度,可以有长度为0的字符串,即空字符串
操做字符串
获取指定位置字符:charAt(int index),返回一个字符
获取对应的字符数组:toCharArray(),返回一个字符数组
截取子字符串:substring(3,5),截取3-4位置的字符,返回一个字符串
根据分隔符进行分隔:split(","),返回一个字符串数组
去掉首尾空格:trim(),返回一个字符串
全部变成小写:toLowerCase ,返回一个字符串
全部变成大写:toUpperCase ,返回一个字符串
判断字符或者子字符串第一次出现的位置; indexOf (),返回一个整型
判断字符或者子字符串最后一次出现的位置; lastIndexOf (),返回一个整型
判断字符或者子字符串在指定位置(5)之后第一次出现的位置; indexOf (",",5),返回一个整型
判断是否包含指定字符串,contains(),返回布尔类型
替换所有指定字符串,replaceAll(),返回一个字符串
替换第一个指定字符串,replaceFirst(),返回一个字符串
比较字符串
是否是同一个对象
String str1 = "hello";
String str2 = new String(str1);
//==用于判断是否为同一个字符串对象
System.out.println( str1 == str2);//结果为false
/***
* 一般说来,编译器每碰到一个字符串的字面值,就会创建一个新的对象
* 所以str1创建了一个新的字符串"hello"
* 但是创建str3时,编译器发现已经存在现成的"hello",那么就直接拿来使用,而没有进行重复创建
*/
String str3 = "hello";
System.out.println( str1 == str3);//结果为ture
内容是否相同
使用equals进行字符串内容的比较,必须大小写一致,equalsIgnoreCase,忽略大小写判断内容是否一致
是否以子字符串开始或者结束
str1.startsWith(str2) //是否以str2开始,str1.endsWith(str2) //是否以str2结束
Stringbuffer
StringBuffer是可变长的字符串
常用方法:append()追加,delete ()删除,insert() 插入,reverse() 反转
StringBuffer维护了一个长度16的字符数组。这个字符数组,留有冗余长度比如说new StringBuffer(“hello”),其内部的字符数组的长度是21,而不是5,这样调用插入和追加,在现成的数组的基础上就可以完成了。如果追加的长度超过了21,就会分配一个新的数组,长度比原来多一些,把原来的数据复制到新的数组中,看上去 数组长度就变长了length: “hello”的长度 5,capacity: 分配的总空间 21,21这个数量,不同的JDK数量是不一样的
练习题
1)自然对数e的计算
借助Math的方法,把自然对数计算出来,看看经过自己计算的自然对数和Math.E的区别有多大
/***
*自然对数的计算方式
*/
public class Exercise {
public static void main(String[] args){
double myE = 1;
int n = Integer.MAX_VALUE;
System.out.println("系 统:\t"+Math.E);
for (int i = 1; i < n; i++) {
myE = myE * (1+(double)1/n);
}
System.out.println("计算的:\t"+myE);
}
}
2)质数计算
统计找出一千万以内,一共有多少质数,质数概念: 只能被1和自己整除的数
/***
*质数计算
* 使用这个Math.sqrt(i),提高效率(不太好理解)
*/
public class Exercise {
public static void main(String[] args){
long start = System.currentTimeMillis();
int count = 0;
boolean isPrimeNumber = true;
for (int i = 2; i <= 10000000; i++) {
// if(i%2==0 && i!=2){continue;}
for (int j = 2; j <= Math.sqrt(i); j++) {
if(i%j == 0){
isPrimeNumber = false;
break;
}
}
if(isPrimeNumber){
count++;
}else{
isPrimeNumber = true;
}
}
System.out.printf("千万以内的质数数量:%d%n",count);
long end = System.currentTimeMillis();
System.out.printf("花费时间: %sms" , (end - start));
}
}
3)练习-Character
通过Scanner从控制台读取字符串,然后把字符串转换为字符数组
参考的转换方式:char[] cs = str.toCharArray();
转换为字符数组后,筛选出控制台读取到的字符串中的大写字母和数字,并打印出来
import java.util.Scanner;
/***
*
* 使练习-Character
*/
public class Exercise {
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入字符串:");
String str = scanner.nextLine();
char[] ch = str.toCharArray();
for (char c : ch) {
if (Character.isUpperCase(c) || Character.isDigit(c)) {
System.out.print(c + "\t");
}
}
}
}
4)练习-随机字符串
创建一个长度是5的随机字符串,随机字符有可能是数字,大写字母或者小写字母
提示:创建随机数字,然后ASCII码转成字符
/***
*48-57数组 65-90大写 97-122小写
* 使练习-Character
*/
public class Exercise {
public static void main(String[] args) {
char[] c = new char[16];
for (int i = 0; i < c.length; i++) {
while (true) {
char rd = (char) (Math.random() * 74 + 48);
//此处也可以用isDigit判断数字,用isLetter判断是不是字母
if ((rd >= 48 && rd <= 57) || (rd >= 65 && rd <= 90) || (rd >= 97 && rd <= 122)) {
c[i] = rd;
break;
}
}
}
System.out.print(String.valueOf(c));
}
}
5)练习-字符串数组排序
创建一个长度是8的字符串数组,使用8个长度是5的随机字符串初始化这个数组,对这个数组进行排序,按 照每个字符串的首字母排序(无视大小写)
注1: 不能使用Arrays.sort() 要自己写
注2: 无视大小写
import java.util.Arrays;
/**
*48-57数字 65-90大写 97-122小写
* 练习-字符串数组排序
*/
public class Exercise {
public static void main(String[] args) {
String[] str = new String[20];
for (int i = 0; i < str.length; i++) {
str[i] = getString();
}
System.out.println(Arrays.toString(str));
sort(str);
System.out.println(Arrays.toString(str));
}
public static String getString() {
char[] c = new char[5];
for (int i = 0; i < c.length; i++) {
while (true) {
char rd = (char) (Math.random() * 74 + 48);
//此处也可以用isDigit判断数字,用isLetter判断是不是字母
if (Character.isDigit(rd) || Character.isLetter(rd)) {
c[i] = rd;
break;
}
}
}
return String.valueOf(c);
}
public static void sort(String[] str) {
String temp ;
for (int i = 0; i < str.length-1; i++) {
for (int j = 0; j < str.length-1-i; j++) {
//忽略大小写就是都转换成小写或大写比较,数值转换大小写不变
if(Character.toLowerCase(str[j].charAt(0)) > Character.toLowerCase(str[j+1].charAt(0))){
temp = str[j];
str[j] = str[j+1];
str[j+1] = temp;
}
}
}
}
}
6)练习-穷举法破解密码
生成一个长度是3的随机字符串,把这个字符串作为当做密码,使用穷举法生成长度是3的字符串,匹配 上述生成的密码
要求: 分别使用多层for循环 和 递归解决上述问题
import java.util.Arrays;
/**
* 三位数密码破解
* 穷举法
*/
public class Exercise {
public static void main(String[] args) {
String str = getString(3);
char[] c = new char[3];//存放待比较的密码
System.out.println(str);
String code = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
// System.out.println(code.substring(1,2));
for (int i = 0; i < 62; i++) {
for (int j = 0; j < 62; j++) {
for (int k = 0; k < 62; k++) {
c[0] = code.charAt(i);
c[1] = code.charAt(j);
c[2] = code.charAt(k);
String str1 = String.valueOf(c);
if (str.equals(str1)) {
System.out.printf("密码为:%s", str1);
i = 62; //猜到密码就终止
j = 62; //猜到密码就终止
break; //猜到密码就终止
}
}
}
}
}
public static String getString(int len) {
char[] c = new char[len];
for (int i = 0; i < c.length; i++) {
while (true) {
char rd = (char) (Math.random() * 74 + 48);
//此处也可以用isDigit判断数字,用isLetter判断是不是字母
if (Character.isDigit(rd) || Character.isLetter(rd)) {
c[i] = rd;
break;
}
}
}
return String.valueOf(c);
}
}
6-1)练习-递归法破解密码
import java.util.Arrays;
/**
* 三位数密码破解
* 递归法
*/
public class Exercise {
public static void main(String[] args) {
String str = getString(3);
String found = new String("");
char[] c = new char[3];//存放待比较的密码
System.out.printf("生成密码为:%s%n",str);
found = getPass(str,found);
System.out.printf("破解密码为:%s%n",found);
}
public static String getString(int len) {
char[] c = new char[len];
for (int i = 0; i < c.length; i++) {
while (true) {
char rd = (char) (Math.random() * 74 + 48);
//此处也可以用isDigit判断数字,用isLetter判断是不是字母
if (Character.isDigit(rd) || Character.isLetter(rd)) {
c[i] = rd;
break;
}
}
}
return String.valueOf(c);
}
/**
* 这个递归是单趟的
* 执行逻辑:
* 1、调用getpass传递随机密码和破解密码
* 2、比较两个密码是否相等
* 不相等的话,遍历62次循环去找出第一个字符
* 如果找到字符,把字符拼接在found里,并且递归进行下一个字符的查找
* 三次递归完成后pass.equals(found)就为true
* 如果找不到字符,return"该密码中包含了特殊字符"
* 相等的话,return一个破解的密码
*
* @param pass 传递进去系统生成的随机密码
* @param found 传递进去破解的密码,首次传递空字符串,
* 第二次递归进去传递的是找到的第一个字符,
* 依次类推,三次递归,就会把found填充到三个字符,也就是密码
* @return 返回破解后的密码
*/
public static String getPass(String pass,String found){
String code = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
if(!pass.equals(found)) {
char[] passChar = pass.toCharArray();
for (int i = 0; i < 62; i++) {
//因为found每次递归完都会给增加一个字符,所以他的length是递增的
//刚好用来指示比较的是哪一个索引
if (passChar[found.length()] == code.charAt(i)) {
found = found + code.charAt(i);
return getPass(pass, found);
}
}
return "该密码中包含了特殊字符";
}
else{
return found;
}
}
}
7)练习-每个单词的首字母都转换为大写
给出一句英文句子: “let there be light”,得到一个新的字符串,每个单词的首字母都转换为大写
import java.util.Arrays;
/**
* 每个单词的首字母都转换为大写
* 65-90大写 97-122小写
*/
public class Exercise {
public static void main(String[] args) {
String str = "you don't have to worry anymore about the window being resized";
System.out.println(str);
String[] strArray = str.split(" ");//以空格分割成字符串数组
for (int i = 0; i < strArray.length; i++) {
if (Character.isLowerCase(strArray[i].charAt(0))) {
char c = Character.toUpperCase(strArray[i].charAt(0));
//第一个字符转换为大写后,必须再转换成字符串,才能使用在replaceFirst中
String firstCharToString = Character.toString(c);
//正则表示式,意思只要第一个字符是a-z全部换成大写
strArray[i] = strArray[i].replaceFirst("[a-z]", firstCharToString);
}
}
String str3 ="";
for (int i = 0; i < strArray.length; i++) {
//最终此处应该使用StringBuffer
str3 = str3 + strArray[i]+" ";
}
System.out.println(str3);
}
}
8)练习-统计以p开头的单词数
peter piper picked a peck of pickled peppers,统计这段绕口令有多少个以p开头的单词
import java.util.Arrays;
/**
* 统计以p开头的单词数
* 65-90大写 97-122小写
*/
public class Exercise {
public static void main(String[] args) {
String str = "peter piper picked a peck of pickled peppers";
System.out.println(str);
int count = 0;
String[] strArray = str.split(" ");//以空格分割成字符串数组
for (int i = 0; i < strArray.length; i++) {
if (strArray[i].charAt(0) == 'p') {
count++;
}
}
System.out.printf("一共有%s个以p开头的单词%n",count);
}
}
9)练习-间隔大写小写模式
把 lengendary 改成间隔大写小写模式,即 LeNgEnDaRy
/**
* 间隔大写小写模式
* 65-90大写 97-122小写
*/
public class Exercise {
public static void main(String[] args) {
String str = "lengendary";
String str1 = "";
System.out.println(str);
for (int i = 0; i < str.length(); i++) {
if (i % 2 == 0) {
str1 = str1 + str.substring(i, i + 1).toUpperCase();
} else {
str1 = str1 + str.substring(i, i + 1);
}
}
System.out.printf("转换后%s%n",str1);
}
}
10)练习-最后一个字母变大写
把 lengendary 最后一个字母变大写
/**
* 最后一个字母变大写
* 65-90大写 97-122小写
*/
public class Exercise {
public static void main(String[] args) {
String str = "lengendary";
String str1 = "";
System.out.println(str);
str1 = str.substring(0,str.length()-1) +Character.toUpperCase(str.charAt(str.length()-1));
System.out.printf("转换后%s%n",str1);
}
}
11)练习-把最后一个目标单词首字母大写
Nature has given us that two ears, two eyes, and but one tongue, to the end that we should hear and see more than we speak,把最后一个two单词首字母大写
/**
* 把最后一个targetString单词首字母大写
* 65-90大写 97-122小写
*/
public class Exercise {
public static void main(String[] args) {
String targetString = "and";
String str = "Nature has given us that two ears, two eyes, and but one tongue" +
", to the end that we should hear and see more than we speak";
String str1 = "";
int index = 0;
System.out.printf("转换后%s%n",str);
index = str.lastIndexOf(targetString);
//目标字符前面字符串+目标字符转大写+目标字符后面的字符串
str1 = str.substring(0,index) + Character.toUpperCase(str.charAt(index))+str.substring(index+1);
System.out.printf("转换后%s%n",str1);
}
}
12)练习-比较字符串
创建一个长度是100的字符串数组,使用长度是2的随机字符填充该字符串数组,统计这个字符串数组里 重复的字符串有多少种
import java.util.Random;
/**
* 比较字符串
* 65-90大写 97-122小写
*/
public class Exercise {
public static void main(String[] args) {
String base = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
String[] strArray = new String[100];
for (int i = 0; i < strArray.length; i++) {
Random rand = new Random();
strArray[i] = "" + base.charAt(rand.nextInt(62)) +
base.charAt(rand.nextInt(62));
System.out.print(strArray[i] + " ");
if ((i + 1) % 20 == 0) {
System.out.println();
}
}
// String[] strArray = {"jh","jh","fg","jh","ds","jh","jh","jh","fg","bv","jh"};
for (int i = 0; i < strArray.length; i++) {
int count = 1;
for (int j = i + 1; j < strArray.length; j++) {
if (strArray[i].equals("")) {//如果是空串不比较,跳过进行下一个元素比较
break;
} else {
if (strArray[i].equals(strArray[j])) {
strArray[j] = "";//把重复字符串置空,让再循环到该空串时,跳过,避免重复比较
count++;
}
}
}
if (count != 1) {
System.out.printf("%s的重复数为%d%n", strArray[i], count);
}
}
}
}
13)练习-StringBuffer性能
生成10位长度的随机字符串,分别使用String的+和StringBuffer,连接10000个随机字符串,计算消耗的 时间
/**
* StringBuffer性能
* 65-90大写 97-122小写
*/
public class Exercise {
public static void main(String[] args) {
String base = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
String str = "";
StringBuffer sb = new StringBuffer();
long stime = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
str += getString(10);
}
long etime = System.currentTimeMillis();
System.out.printf("用+号总花费时间:%dms%n", etime - stime);
long stime1 = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
sb.append(getString(10));
}
long etime1 = System.currentTimeMillis();
System.out.printf("用StringBuffer总花费时间:%dms%n", etime1 - stime1);
}
public static String getString(int len) {
char[] c = new char[len];
for (int i = 0; i < c.length; i++) {
while (true) {
char rd = (char) (Math.random() * 74 + 48);
//此处也可以用isDigit判断数字,用isLetter判断是不是字母
if (Character.isDigit(rd) || Character.isLetter(rd)) {
c[i] = rd;
break;
}
}
}
return String.valueOf(c);
}
}
14)练习-MyStringBuffer
Exercise.java
/**
* MyStringBuffer性能
* 65-90大写 97-122小写
*/
public class Exercise{
public static void main(String[] args) {
MyStringBuffer sb = new MyStringBuffer("abc");
System.out.println(sb.length());
System.out.println(sb.capacity());
System.out.println(sb.toString());
sb.append("123");
System.out.println(sb.length());
System.out.println(sb.capacity());
System.out.println(sb.toString());
sb.append("987654321");
System.out.println(sb.length());
System.out.println(sb.capacity());
System.out.println(sb.toString());
sb.append('w');
System.out.println(sb.length());
System.out.println(sb.capacity());
System.out.println(sb.toString());
sb.insert(4,'o');
System.out.println(sb.length());
System.out.println(sb.capacity());
System.out.println(sb.toString());
sb.insert(5,"WCO");
System.out.println(sb.length());
System.out.println(sb.capacity());
System.out.println(sb.toString());
sb.delete(5,8);
System.out.println(sb.length());
System.out.println(sb.capacity());
System.out.println(sb.toString());
sb.reverse();
System.out.println(sb.length());
System.out.println(sb.capacity());
System.out.println(sb.toString());
}
}
MyStringBuffer.java
public class MyStringBuffer implements InterfaceStringBuffer {
private char[] ch; //内部管理的个字符数组
private int len; // 全局都要使用的数组内有效元素的个数
public MyStringBuffer() {
ch = new char[16];//创建对象要默认创建一个大小16的空数组
}
public MyStringBuffer(String str) {
ch = new char[16];
append(str);//当创建对象时传递了一个字符串,则调用内部的append去添加
}
@Override
public void append(String str) {
insert(len,str);
}
@Override
public void append(char c) {
insert(len,c);
}
@Override
public void insert(int pos, char b) {
insert(pos,String.valueOf(b));
}
@Override
public void insert(int pos, String b) {
if(pos < 0 || pos>len){
return;
}
char[] c = b.toCharArray();
char[] temp = new char[capacity()];
while (len+c.length > temp.length){//一步一步扩容
temp = new char[temp.length*2 + 2];//原数组要进行扩容
}
System.arraycopy(ch, 0, temp, 0, pos);
System.arraycopy(c, 0, temp, pos, c.length);
System.arraycopy(ch, pos, temp, pos + c.length, len - pos);
ch = temp;
len = len + b.length();
}
@Override
public void delete(int start) {
delete(start,len);
}
@Override
public void delete(int start, int end) {
/*
* 总体思想就是清零ch数组
* 再把删除后的数组元素一个一个append进去
* 这样可以避免过分关注ch数组大小和有效元素的问题
* 全部由append去处理,最终还是由insert处理
* 所以insert一定要写全面一点
*/
if (end - start <= 0) {
return;
}
if (start < 0) {
return;
}
if (end > len) {
return;
}
char[] temp = ch; //把ch数组缓存
ch = new char[16];//ch数组清零
int lentemp = len;//长度缓存,到时循环时需要用到
len = 0;//ch都清零了,配套的len也得清零
for (int i = 0; i < start; i++) {
append(temp[i]);
}
for (int i = end; i < lentemp; i++) {
append(temp[i]);
}
}
@Override
public void reverse() {
char[] temp = new char[capacity()];
for (int i = 0; i < len; i++) {
System.arraycopy(ch, i, temp, len - 1 - i, 1);
}
ch = temp;
}
@Override
public int length() {
return len;
}
public int capacity() {
return ch.length;
}
public String toString() {
char[] temp = new char[len];
System.arraycopy(ch, 0, temp, 0, len);//避免打印后字符串后面有很多空字符
return String.valueOf(temp);
}
}
InterfaceStringBuffer.java
public interface InterfaceStringBuffer {
public void append(String str); //追加字符串
public void append(char c); //追加字符
public void insert(int pos,char b); //指定位置插入字符
public void insert(int pos,String b); //指定位置插入字符串
public void delete(int start); //从开始位置删除剩下的
public void delete(int start,int end); //从开始位置删除结束位置-1
public void reverse(); //反转
public int length(); //返回长度
}