String类
String类不能被继承
通过源码可以看到String类前面加了final修饰,因此String类是不能够被继承的。将其设置为不能被继承的原因是为了减少歧义。
字符串(String)的不可变性
String创建好之后值是不可以被改变的,这里指的是在堆中的字符串的值是不可以被改变
package com.charter06.string;
public class StringTest01 {
public static void main(String[] args) {
String s1 = "monkey1024";
String s2 = "monkey1024";
s1 = "good";
String s3 = "hello";
String s4 = "hello";//开辟了一个 常量池
String s5 = new String("monkey");
String s6 = new String("monkey");//开辟了两个空间 常量池 堆
System.out.println(s3==s4);//true
System.out.println(s3.equals(s4));//true
System.out.println(s5.equals(s6));//true
System.out.println(s5==s6);//false
System.out.println("==========");
String s7 = "a";
String s8 = "b";
String s9 = "ab";
String s10 = s7+s8;//开辟新的内存空间
//尽量避免对String对象进行频繁拼接
System.out.println(s10);
System.out.println(s10==s9);//false
}
}
String常用方法
package com.charter06.string;
public class StringTest02 {
public static void main(String[] args) {
String s1 = "monkey1024";
// char charAt(int index); 获取index位置的字符
System.out.println(s1.charAt(5));
//boolean contains(charSequence s);判断字符串中是否包含某个字符串
System.out.println(s1.contains("1024"));
//boolean endsWith(String endStr);判断是否以某个字符串结尾
System.out.println(s1.endsWith("24"));
//boolean startsWith(String staStr);判断是否以某个字符串开始
System.out.println(s1.startsWith("mo"));
//boolean equalsIgnoreCase(String anotherString);//忽略大小写去比较字符串是否相等
System.out.println(s1.equalsIgnoreCase("Monkey1024"));
//byte[] getBytes();转换成byte数组
String s2 = "abc";
byte[] bytes = s2.getBytes();
for (int i = 0; i < bytes.length; i++) {
System.out.println(bytes[i]);
}
//int indexOf(String str);取得指定字符在字符串的位置
System.out.println(s2.indexOf("c"));
//int indexOf(String str,itn fromIndex);从指定的下标开始取指定字符在字符串的位置
String s3 = "monkey1024monkey";
System.out.println(s3.indexOf("y",6));
//int lastIndexOf(String str);从后面开始取得指定字符在字符串最后出现的位置
String s4 = "monkey1024monkeyyyy";
System.out.println(s4.lastIndexOf("y"));
//int lastIndexOf(String str,int formIndex);从后面指定的下标取指定字符在字符串最后出现的位置
System.out.println(s4.lastIndexOf("y",14));
//int length();获取字符串的长度
System.out.println(s4.length());
//String replaceAll(String s1,String s2);替换字符串中的内容
System.out.println(s4.replace("y","b"));
//String[] split(String s); 根据指定的表达式拆分字符串
String s5 = "a,b,c,d";
String[] split = s5.split(",");
for(int i = 0;i<split.length;i++){
System.out.print(split[i]);//abcd
}
System.out.println();
//String subString(int begin);//根据传入的索引位置截断字符串
System.out.println(s5.substring(1));//,b,c,d
//String subString(int beginIndex,int endIndex);根据传入的开始和结束索引截断字符串
System.out.println(s5.substring(1,5));//,b,c
//char[] toCharArray();将字符串转换为char数组
System.out.println(s5.toCharArray());
//void toUpperCase();转换为大写
String s6 = "hhaHHHjs";
System.out.println(s6.toUpperCase());
//void toLowerCase();转换为小写
System.out.println(s6.toLowerCase());
//String trim();去除首位空格
String s7 = " java good ok ";
System.out.println(s7.trim());
//String valueOf(Object obj);将其他类型转换为字符串类型
int s8 = 12344;
System.out.println(String.valueOf(s8));
}
}
1.String s4 = “hello”;//开辟了一个 常量池
2.String s6 = new String(“monkey”);//开辟了两个空间 常量池 堆
3.比较两个字符串是否一致最好使用equals方法
问题:下面代码创建了几个对象?
String s1 = new String("www.monkey1024.com");
String s2 = new String("www.monkey1024.com");
答案
堆:两个
常量池:1个
正则表达式
package com.charter06.string;
public class Regex {
public static void main(String[] args) {
//将下列字符串的数字修改为”中“
String s1 = "mogdfs2bh23hh3kh5h3k2";
System.out.println(s1.replaceAll("\\d","中"));//mogdfs中bh中中hh中kh中h中k中
//matches检测字符串是否匹配给定的正则表达式。
String email = "2231806407@qq.com";
System.out.println(email.matches("^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$"));//true
String phone = "15730735950";
System.out.println(phone.matches("^1[0-9]{10}$"));//true
}
}
练习1
字符串反转,例如将"abc"变成"cba"
package com.charter06.string;
public class Exercise {
public static void main(String[] args) {
String s = "abc";
char[] chars = s.toCharArray();
for (int i = chars.length-1; i >= 0 ; i--) {
System.out.print(chars[i]);
}
}
}
练习2
统计一个字符串里面另一个字符串出现的次数
package com.charter06.string;
public class Exercise02 {
public static void main(String[] args) {
String big = "abbbaggs";
String small = "a";
//统计small在big中出现的次数
//用来统计次数
int count = 0;
//索引值
int index = 0;
//获取索引值
while ((index = big.indexOf(small))!=-1){
count++;
//对 big进行截取 ,截取的索引位置是index+small的长度
big = big.substring(index + (small.length()));
}
System.out.println(count);
}
}
练习3
统计一个字符串中大写字母出现的次数
package com.charter06.string;
public class Exercise03 {
public static void main(String[] args) {
//统计一个字符串中大写出现的次数
String b = "AaAbbbAAAA";
String B = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int count = 0;
for (int i = 0; i < b.length(); i++) {
if (B.indexOf(b.charAt(i)) != -1){
count++;
}
}
System.out.println(count);
}
}
StringBuffer和StringBuilder
每次对字符串修改,底层都会重新开辟新的堆内存空间,这样会开辟很多个空间地址,造成浪费。
如果需要对字符串进行频繁拼接的话,建议使用StringBuffer或者StringBuilder,两者的使用方法一致,下面以StringBuffer为例说明。
StringBuffer是一个字符串缓冲区,如果需要频繁的对字符串进行拼接时,建议使用StringBuffer。
String与StringBuffer的区别?
String是不可变字符序列,存储在字符串常量池中
StringBuffer的底层是byte数组,系统会对该数组进行扩容
package com.charter06.string;
public class StringBuffer01 {
public static void main(String[] args) {
//如果没有明确指出,则系统默认长度是16
StringBuffer sb = new StringBuffer();
System.out.println(sb.capacity());//16
//建议预估字符串的长度,并且声明StringBuffer的长度
StringBuffer sb01 = new StringBuffer(4);
System.out.println(sb01.capacity());//4
//如果传入String类型,则初始化长度为String.length+16
StringBuffer sb02 = new StringBuffer("zhouxiang");
System.out.println(sb02.capacity());//16+9
}
}
package com.charter06.string;
public class StringBuffer02 {
public static void main(String[] args) {
StringBuffer sb01 = new StringBuffer(30);
sb01.append("www");
sb01.append(".");
sb01.append("monkey1024");
sb01.append(".");
sb01.append("com");
System.out.println(sb01);//www.monkey1024.com
System.out.println(sb01.toString());//会自动调用toString()方法
//在指定位置插入字符串
sb01.insert(4,1204);//www.1204monkey1024.com
System.out.println(sb01);
//将指定位置删除字符串
sb01.delete(4,8);
System.out.println(sb01);//www.monkey1024.com
}
}
package com.charter06.string;public class StringBuffer03 { public static void main(String[] args) { //基本数据类型,值不会变 //引用数据类型,值不会改变(String类除外) String s = "String"; System.out.println(s);//String change(s); System.out.println(s);//String StringBuffer bs = new StringBuffer(30); change(bs); System.out.println(bs);//java bs.append("StringBuffer"); System.out.println(bs);//javaStringBuffer } public static void change(String s){ s+="java"; } public static void change(StringBuffer sb){ sb.append("java"); }}
package com.charter06.string;public class StringBuilder { //api里面的方法都是相同的 //StringBuffer 是线程安全的 ,效率低 //StringBuilder 是线程不安全的 , 效率高}
基本类型和包装类
包装类
什么是包装类
Java里面8个基本数据类型都有相应的类,这些类叫做包装类
包装类的优点
可以在对象中定义更多的功能方法操作该数据,方便开发者操作数据,例如基本数据类型和字符串之间的转换。
基本数据类型和对应的包装类
基本数据类型 包装类 byte Byte short Short int Integer long Long float Float double Double char Character boolean Boolean
package com.charter06.wrap;public class Integer01 { public static void main(String[] args) { //int类型的最大值 System.out.println(Integer.MAX_VALUE); //int类型的最小值 System.out.println(Integer.MIN_VALUE); Integer i1 = new Integer(100); System.out.println(i1); //括号中的字符串必须是数字才行 Integer i2 = new Integer("1024"); System.out.println(i2); //把Integer类型转为int类型 int i3 = i2.intValue(); System.out.println(i3); //将数字字符串转换为int类型 int i4 = Integer.parseInt("100"); //将int类型转换为Integer类型 Integer i5 = Integer.valueOf(8); //将十进制分别转换为二,八,十六进制 String s1 = Integer.toBinaryString(10); String s2 = Integer.toOctalString(10); String s3 = Integer.toHexString(10); System.out.println(s1); System.out.println(s2); System.out.println(s3); }}
package com.charter06.wrap;public class Integer02 { public static void main(String[] args) { //Integer.int,String 三者之间的转换 //int-->Integer Integer i1 = Integer.valueOf(10); //Integer-->int int i2 = i1.intValue(); //int-->String String s2 = 10+""; //String-->Integer Integer i3 = Integer.valueOf("10"); //Integer-->String String s1 = i3.toString(); //String-->int int i4 = Integer.parseInt("10"); }}
package com.charter06.wrap;public class Box01 { public static void main(String[] args) { //Jdk5加入 //自动装箱,就是将基本数据类型自动转换其对应的包装类 Integer i1 = 10; //自动拆箱 Integer i2 = new Integer(20); int i3 = i2; Integer i4 = 128; Integer i5 = 128;//相当于创建了Integer i5 = new Integer(888); System.out.println(i4==i5);//false System.out.println(i4.equals(i5));//true Integer i6 = 127; Integer i7 = 127; System.out.println(i6==i7);//true //整型常量池,如果值在-128~127之间的时候,会在整型常量池里面直接获取 }}
日期类型
获取毫秒数
工作中基本上都会需要使用对时间的操作,java也提供了一些时间相关的类。
下面代码可以获取自 1970年1月1日 00时00分00秒 000毫秒 到当前的毫秒数。
package com.charter06.data;public class Data01 { public static void main(String[] args) { //从1970年1月1日00时0分0秒000毫秒到现在所过的毫秒数 long now = System.currentTimeMillis(); System.out.println(now); //分别演示String和StringBuffer拼接1000次所消耗的时间 String s = ""; StringBuffer sb = new StringBuffer(1000); long before = System.currentTimeMillis(); for (int i = 0; i < 1000; i++) {// s+=i;//最快是9 sb.append(i);//1 } long after = System.currentTimeMillis(); System.out.println(after-before); }}
package com.charter06.data;import java.text.SimpleDateFormat;import java.util.Date;public class Data02 { public static void main(String[] args) { //获取系统当前时间 Date date = new Date(); System.out.println(date);//默认使用toString()方法 Date date1 = new Date(0L); System.out.println(date1);//打印结果1970年1月1日 //Y-年 M-月 d-日 h-时 m-分 s-秒 S-毫秒 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss SSS"); SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy年MM月dd日hh时mm分ss秒SSS毫秒"); sdf.format(date);//是String类型 sdf1.format(date); System.out.println(sdf.format(date)); System.out.println(sdf1.format(date)); }}
package com.charter06.data;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;public class Date03 { public static void main(String[] args) throws ParseException { //将String类型转换为Date类型 String s = "2021年10月13日06时21分21秒638毫秒"; SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日hh时mm分ss秒SSS毫秒"); Date parse = sdf.parse(s); char c4 = 97; System.out.println(c4); }}
package com.charter06.data;import java.text.ParseException;import java.util.Calendar;public class Date04 { public static void main(String[] args) throws ParseException { Calendar c = Calendar.getInstance(); System.out.println(c.get(Calendar.DAY_OF_WEEK));//美国人将周日当作一周的第一天 System.out.println(c.get(Calendar.DAY_OF_MONTH)); }}
练习
查看2008年8月8日是星期几
package com.charter06.data;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;public class Exercise01 { public static void main(String[] args) throws ParseException { //查看2008年8月8日是星期几 String s = "2008年8月8日"; SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日"); Date parse = sdf.parse(s); Calendar c = Calendar.getInstance(); c.setTime(parse); System.out.println(c.get(Calendar.DAY_OF_WEEK)); }}
计算自己来世上多少天
package com.charter06.data;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;public class Exercise02 { public static void main(String[] args) throws ParseException { //计算自己来世上多少天 //分析:用当前日期的毫秒数减去出生那天的毫秒数,将毫秒数转换为天数 Date date = new Date(); String s = "2000年3月15日"; SimpleDateFormat sdf = new SimpleDateFormat("YYYY年MM月dd日"); Date parse = sdf.parse(s); long now = date.getTime(); long before = parse.getTime(); long l = now - before; System.out.println(l/86400000); }}
Math类
这个类包含了用于执行基本数学运算的方法
package com.charter06.math;public class Math01 { public static void main(String[] args) { //圆周率 System.out.println(Math.PI); //取绝对值 System.out.println(Math.abs(-1)); //天花板 System.out.println(Math.ceil(12.3));//13 System.out.println(Math.ceil(12.9));//13 //地板 System.out.println(Math.floor(12.3)); System.out.println(Math.floor(12.9)); //输出两者最大的一个数 System.out.println(Math.max(12,3)); //x的n次方 System.out.println(Math.pow(2,3));//8.0 //输出随机小数[0.0,1.0) System.out.println(Math.random()); //四舍五入 System.out.println(Math.round(12.4));//12 System.out.println(Math.round(12.5));//13 //开平方根 System.out.println(Math.sqrt(16));//4 System.out.println(Math.sqrt(2)); }}
BigInteger类
BigInteger类可以让超过Integer范围的数据进行运算,通常在对数字计算比较大的行业中应用的多一些
package com.charter06.big;import java.math.BigInteger;public class BigInteger01 { //适用于数比较大的时候 public static void main(String[] args) { BigInteger bi1 = new BigInteger("120"); BigInteger bi2 = new BigInteger("2"); //bi1加bi2 System.out.println(bi1.add(bi2)); //bi1减bi2 System.out.println(bi1.subtract(bi2)); //bi1乘bi2 System.out.println(bi1.multiply(bi2)); //bi1除bi2 System.out.println(bi1.divide(bi2)); //返回除数和余数 BigInteger[] array = bi1.divideAndRemainder(bi2); for (int i = 0; i < array.length; i++) { System.out.println(array[i]); } }}
BigDecimal类
如果对计算的数据要求高精度时,必须使用BigDecimal类
package com.charter06.big;import java.math.BigDecimal;public class BigDecimal01 { public static void main(String[] args) { System.out.println(2.0-1.1);//0.8999999999999999 //开发中不要这样写,还是不够精确 BigDecimal bd1 = new BigDecimal(2.0); BigDecimal bd2 = new BigDecimal(1.1); System.out.println(bd1.subtract(bd2));//0.899999999999999911182158029987476766109466552734375 //括号里面传字符串 //开发中建议这样使用 BigDecimal bd3 = new BigDecimal("2.0"); BigDecimal bd4 = new BigDecimal("1.1"); System.out.println(bd3.subtract(bd4));//0.9 //也可以这样 BigDecimal bd5 = BigDecimal.valueOf(2.0); BigDecimal bd6 = BigDecimal.valueOf(1.1); System.out.println(bd5.subtract(bd6));//0.9 }}
DecimalFormat类
在一些金融或者银行的业务里面,会出现这样千分位格式的数字,¥123,456.00,表示人民币壹拾贰万叁仟肆佰伍拾陆元整
package com.charter06.big;import java.text.DecimalFormat;public class DecimalFormat01 { public static void main(String[] args) { //将一个数字转换为人民币的格式 String RMB = DecimalFormat.getCurrencyInstance().format(123456); System.out.println(RMB);//¥123,456.00 //自定义格式 DecimalFormat df1 = new DecimalFormat("###,###"); System.out.println(df1.format(123456));//123,456 DecimalFormat df2 = new DecimalFormat("###,###.##"); System.out.println(df2.format(123456.123));//123,456.12 //小数没有的自动补齐 DecimalFormat df3 = new DecimalFormat("###,###.0000"); System.out.println(df3.format(123456.123));//123,456.1230 }}
enum(JDK5)
在日常开发中可能有一些东西是固定的,比如一年只有4个季节,春夏秋冬。我们可以自己定义一个类里面存放这4个季节。在jdk5之后,引入了枚举(enum)的概念,可以通过enum去定义这四个季节。
package com.charter06.eun;
public class Enum {
//枚举与常量类都可以
public enum Season{
Spring,Summer,Autumn,Winter
}
public static void main(String[] args) {
System.out.println(Season.Autumn);
System.out.println(Constant.SPRING);
}
}
package com.charter06.eun;
public class Constant {
//定义常量类
public static final String SPRING = "spring";
public static final String SUMMER = "summer";
public static final String AUTUMN = "autumn";
public static final String WINTER = "winter";
}
Random类
使用这个类可以生成随机数
package com.charter06.random;
import java.util.Random;
public class Random01 {
public static void main(String[] args) {
Random random = new Random();
System.out.println(random.nextInt(101));//随机生成0~100之间的数字
}
}
完成一个彩票机选号码生成器,这里以双色球为例
package com.charter06.random;
import java.util.Arrays;
import java.util.Random;
public class Test {
//完成一个彩票机选号码生成器,这里以双色球为例,
//双色球每注中奖号码由6个不同的红色球号码和1个蓝色球号码组成。红色球号码从1~33中选择;蓝色球号码从1~16中选择。
public static void main(String[] args) {
//初始化双色球号码
int[] balls = new int[33];
for(int i=0; i<balls.length; i++){
balls[i] = i + 1;
}
//创建数组用来标记红球是否重复
boolean[] isUsed = new boolean[33];
//创建数组用来存放6个红球
int[] result = new int[6];
//初始化数组下标
int length = 0;
Random r = new Random();
while(true){
//生成0~32的随机数,将随机数作为数组下标,取得红球
int red = r.nextInt(33);
//判断生成的红球是否重复
if(isUsed[red] == true){
continue;
}
//将选中的红球存放到结果中
result[length++] = balls[red];
//如果等于6则说明已经生成了6个红球了,跳出循环
if(length == 6){
break;
}
//将生成的红球所对应的数组下标标记为true
isUsed[red] = true;
}
//将数组排序
Arrays.sort(result);
//生成0~15的随机数,将随机数作为数组下标,取得蓝球
int blue = r.nextInt(16);
//将红球打印
System.out.print("红球:");
for(int i=0; i<result.length; i++){
if(i == result.length - 1){
System.out.print(result[i]);
}else{
System.out.print(result[i] + ",");
}
}
//将蓝球打印
System.out.print(" 蓝球:" + balls[blue]);
}
}