一.使用包装类
Integer类继承了Number父类和Comparable父接口(所以自身具有比较方法compareTo())。Integer类里面唯一的一个属性(private final int value),8中基本包装类,每一种对象里面都包含了一个对应的value值,Byte里面包含一个byte的,Boolean的里面包含一个boolean的,如下所示:
| 源码:public final class Integer extends Number implements Comparable {} 说明:继承了Number和内部比较器 |
|---|
| 源码: Integer属性有个value: private final int value; |
| – |
| 源码: Boolean属性也有个value: private final boolean value; |
从这里我们可以得到包装类的特点:
Integer类的唯一的一个实例成员:private final int value;
该类的对象一旦创建就不能被修改。对象不可改变的特点。
包装类的优缺点
优点:安全。多个线程同时访问一个对象,因为不能修改,是只读的,所以是安全的。
缺点:当你需要使用不同value值的Integer对象的时候,需要创建多个Integer对象(比如需要10个Integer对象就必须得new10次)。对象不能复用(我修改你的值再去用)。造成内存的浪费。
4.包装类继承体系图

5.Integer类的基本使用
Integer类的一些常用方法,如下表所示:
| int | compareTo(Integer anotherInteger) 在数字上比较两个 Integer 对象。 |
|---|---|
| static Integer | decode(String nm) 将 String 解码为 Integer。 |
| boolean | equals(Object obj) 比较此对象与指定对象 |
| int | hashCode() 返回此 Integer 的哈希码。 |
| int | intValue() 以 int 类型返回该 Integer 的值。 |
| static int | parseInt(String s) 将字符串参数作为有符号的十进制整数进行解析。 |
| String | toString() 返回一个表示该 Integer 值的 String 对象 |
二、自动装箱和拆箱
在jdk1.5之后针对8种包装类,推出了一种新的创建对象的语法。
自动装箱autoboxing:将一个基本数据类型的数据,直接赋值给对应包装类对象的过程;底层通过调用integer.valueOf()实现的
自动拆箱autounbxing:将一个包装类对象直接赋值给一个对应的基本数据类型的过程,底层通过intValue()实现。
import java.util.Arrays;
/**
*Integer类的基本使用
*/
public class TestInteger{
public static void main(String[] args) {
//test();
test3();
}
public static void test(){
//创建Integer对象
Integer integer=new Integer(10);
integer=new Integer("123");
//可以使用Integer里面的静态工厂方法创建对象
integer=Integer.valueOf(234);
integer=Integer.valueOf("ff",16);//255,用16进制解析这个字符串,返回它对应的整数值作为包装类对象。
System.out.println(integer);//调用的是它的toString方法,Integer重写了这个方法
/*
Integer里面byteValue的源码(其实这里面就是强制类型转换)
public byte byteValue() {
return (byte)value;
}
*/
System.out.println(integer.byteValue());//将255强制转换为byte类型,返回-1(超过了byte的表示范围,所以返回的值为-1)
/*
intValue()方法的源码,其实相当于get方法
public int intValue() {
return value;
}
*/
System.out.println(integer);//255
System.out.println(integer.intValue());//255
System.out.println(integer.compareTo(new Integer("123")));//返回1
//parseInt()是静态方法,所以用类名访问
System.out.println(Integer.parseInt("123"+1));//124
//用二进制解析这个字符串,
System.out.println(Integer.parseInt("1111",2)+1);//16
}
//此方法用于测试自动装箱和拆箱
private static void test1(){
Integer integer=1;//可以把一个基本数据类型的值或者变量,直接赋值给给它对应的包装类对象
int age=10;//将一个对象(里面的值)直接赋值给了一个变量
/*这句代码只是语法上是这样的,编译之后就变样了。自动装箱和自动拆箱只是对于程序员来说简单的语法而已,编译之后class文件中的内容是:
integer=integer.valueOf(age)
*/
Integer integer1=age;//也可以把一个基本数据类型的变量,直接赋值给它所对应的包装类对象。
Boolean bool=true;
//自动拆箱(jdk1.5之前去对象里取一个数值需要调用inValue()方法来实现同样的功能)
age=integer;//直接将一个对象(里面装的值)赋值给对应的基本数据类型的变量
/*
自动拆箱在class文件中的内容:
age=integer.intValue();
*/
}
//定义Integer数组,长度为5,然后静态初始化
//使用自动装箱随机初始化,然后打印数组内容
//然后使用Arrays排序,然后打印
static void test2(){
Integer[] integers={
getRandomNumber(10,50),
getRandomNumber(10,50),
getRandomNumber(10,50),
getRandomNumber(10,50),
getRandomNumber(10,50)
};
System.out.println(Arrays.toString(integers));
Arrays.sort(integers);//Arrays.sort()的这个sort()方法在底层也是通过comparable来进行比较的
//Integer已经实现了内部比较器
/*Integer 实现了内部比较器功能
public int compareTo(Integer anotherInteger) {
return compare(this.value, anotherInteger.value);
}
*/
System.out.println(Arrays.toString(integers));
}
//定义一个生成一个随机数方法
public static int getRandomNumber(int min,int max){
return (int)(Math.random()*(max-min)+min);
}
//一道面试题
public static void test3(){
//只要使用了new一定是个新对象
Integer integer0=new Integer(10);
Integer integer1=new Integer(10);
System.out.println(integer0 == integer1);//false 这两个是new出来的,很显然是两个不同的对象,所以结果是false
//这里是同一个对象,这就是使用静态工厂方法带来的优点,静态工厂方法虽然也创建对象了,但是在底层实现的时候不一定调用的new
/*valueOf的底层实现,如果这个i大于.low(-128)或者小于.high(127),返回
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
---------------------------------------------------------------------------------------------------------------
返回来的static final Integer cache[];使用static final 修饰的,
Integer对象有一个缺点,一旦创建就不能改变,
如果我们需要不同的Integer对象,需要不停的new。。。这时候会造成内存的浪费,因此JDK针对这个特点提供了什么机制呢?
它在Integer 类加载的时候,提前创建好了256个Integer对象[-128,127],放在了cache[] 这个数组里面了。这叫对象池,
提前创建好一堆对象,当用的时候,直接在里面拿就可以了。
要注意在类加载的时候就创建好了,那么怎么使用呢,如果我们用valueOf创建的对象再它这个范围内,则用它已经创建好的。
如果不在这个区间,则用new Integer(i);创建一个新的对象。
那么用什么得到这256个对象呢?用valueOf()得到
*/
Integer integer2=Integer.valueOf(10);
Integer integer3=Integer.valueOf(10);
System.out.println(integer2 == integer3);//true
Integer integer4=Integer.valueOf(128);
Integer integer5=Integer.valueOf(128);
System.out.println(integer4 == integer5);//false
}
}
第三节Java.lang.String
1.前言:
String 类是用来描述字符串对象的,任何一个字符串常量都是该类的一个实例。”123” 是一个String对象。
2.特点
1:实现了内部比较器接口java.lang.Comparable 可以进行内部比较。compareTo()
| 源码: public final class String implements java.io.Serializable, Comparable, CharSequence { } 说明:String类继承了后面那3个接口 |
|---|
2:final 修饰该类,不能有子类。
3:String类底层使用char[] 实现对字符序列的存储。
3.常用方法练习
| String | 构造方法 public String(char value[]) } |
|---|---|
| String | 构造方法 public String(String original) |
| String | 构造方法 public String(char value[], int offset, int count) |
| 剩下的常用方法,见下面代码 |
import java.util.Arrays;
/**
*String方法练习
*/
public class TestString {
public static void main(String[] args) {
test0();
}
//String方法练习
public static void test0() {
byte[] bs = {65, 66, 67, 68};
String str = new String(bs); //将一个字节数组生成了一个字符串对象
System.out.println(str);// 打印结果为ABCD,所以这里的65是对应的ASIIC码里面的值
String str1 = new String("123456789");
System.out.println(str1);
System.out.println(str1.charAt(3));//返回String对象里面指定索引位置的字符,是个char类型
System.out.println("bc".compareTo("be"));//返回-2。
System.out.println("bc".concat("de"));//字符串的连接,返回bcde
System.out.println(str1.contains("34"));//str这个对象里面是否包含了子串"34" //true
System.out.println(str1.endsWith("789"));//这个字符串是不是以什么什么结尾。//true
System.out.println(str1.startsWith("123"));//这个字符串是不是以什么什么开头。//true
//这里又new出来一个新的对象,因为String重写了equals()方法,所以这里是根据内容比较。内容相同返回true
System.out.println(str1.equals(new String("123456789"))); //true
//下面的这个方法是一个静态方法。(了解)
// 前面有三个特殊符号,则后面就要传进来3个参数。不同的符号接收不同的变参的内容,最后返回格式化后的结果
System.out.println(String.format("%s攻击了%s,受到了%d点伤害", "阿基里斯","赫克托", 100));
//这里讲一个字符串还原成一个【字节数组】
//我们想一下"123456789"对应的字节数组是啥样的?1对应的是49,2对应50,51,52,..............
//打印的结果[49,50,51,52,53,54,55,56,57]
System.out.println(Arrays.toString(str1.getBytes()));//str1.getBytes()这是一个字节数组
System.out.println(str1.indexOf('1'));//在这个字符串里面第一个出现'1'这个字符的索引的位置 //结果0
System.out.println(str1.indexOf("54"));//也可以是字符串,这个字符串不存在,返回-1;
System.out.println(str1.isEmpty());//返回false
System.out.println(str1.lastIndexOf("23"));//从后向前找,但是索引还是从前向后数。//返回1
System.out.println(str1.length());//字符串的长度9
System.out.println(str1.replace("4","68"));//返回新的字符串对象1236856789
////以下划线分割符,返回切割后的数组//[java, c, c#, php]
System.out.println(Arrays.toString("java_c_c#_php".split("_")));
//注意到这里这个str1还是"123456789"
//求子串的,从7到末尾
System.out.println(str1.substring(7));// 结果为:89
System.out.println(str1.substring(3,6));//返回子串,包含3,不包含6 //结果:456
System.out.println("abc".toUpperCase());//转为大写 //结果为ABC
System.out.println("ABC".toLowerCase());//转为小写 //结果为abc
//对这个字符串前导空白字符和后延空白字符去掉,注意中间的去不掉
System.out.println(" a b c ".trim());//输出结果a b c
//剩下的valueOf(),是重载,是静态的方法,将8种基本数据类型的数据转换为字符串的方法,返回的是String
//返回的是1的字符串对象,这个是有int转换为String,那么是怎么转换的呢?依赖于Integer里面的int到String
/*源码:
public static String valueOf(int i) {
return Integer.toString(i);
}
*/
System.out.println(String.valueOf(1));
//也可以将一个对象转换为字符串
//将对象转换为字符串都依赖于对象的toString方法,也就是底层依赖的是对象的toString()方法。
//由于这个对象的toString(),我们没有重写,所以用过的是父类的toString方法
/*
public static String valueOf(Object obj) { //这里存在多态,父类引用指向子类对象
return (obj == null) ? "null" : obj.toString();
}
*/
System.out.println(String.valueOf(new TestString())); //结果为:com.sxt.first.TestString@5cad8086
}
//练习1:实现方法:对应任意的字符串,判断字符串中是否包含了数字。
public boolean hasNumber(String str){
if(str==null) return false; //判断特殊情况
final int LEN=str.length();
if(LEN==0) return false; //判断特殊情况
for (int i = 0; i < LEN; i++) {
char ch=str.charAt(i);
if(ch>='0' && ch<= '9'){ //或者这里将'0'改为48,'9'改为57也可以但是可读性不好
return true;
}
}
return false;
}
//练习2:实现方法:统计任意的的字符串中,包含指定字符的个数。
public int test4(String str,char ch){
if(str==null) return 0; //特殊情况处理
final int LEN=str.length();
if(LEN==0) return 0; //特殊情况处理
int count=0;//定义一个计数器
for (int i = 0; i < LEN; i++) {
if(ch==str.charAt(i)){
count++;
}
}
return count;
}
}
字符串"123456789"在对象里面是以什么形式存储的呢?也就是说字符串在底层使用什么来实现具体字符的保存方式的?
| 看源码:/** The value is used for character storage. */ private final char value[]; |
|---|
也就是说String类的底层实现是使用char[] 数组来保存这些字符的。而且是私有的,用final修饰的。用final修饰的意味着什么?我们以前说过,final修饰的引用数据类型意味着不能再指向其他对象,在这里也就是说这个value不能指向其他数组了。数组的特点是长度固定。那么我们一旦确定了数组,则长度不能变。那么**数组内容可不可以变呢?**通过下面的代码证明,可以。
//测试用final修饰的数组的内容可不可以改变?
public class Test{
public static void main(String[] args) {
final char value[]={'1','2'};
//value=new char[10];//这行报错,value不能再指向另外一个数组了。
//那么里面的内容能不能改变呢?
value[0]='a';
System.out.println(Arrays.toString(value)); //结果为[a,2].结论是可以修改字符的内容的。
}
}
但是这个类是private 的,并且没有提供set方法,也就是对外没有提供修改value的方法,综上可知:
**Final 修饰value,所以final不能指向其他的数组,那么数组一旦长度确定了,就不能修改了,然后String类又没有提供让我们修改元素的方法,不能通过方法修改value 的值。所以得出一个String对象最大的特点:对象一旦创建就不能修改了。
**
优点:线程安全。
缺点:在修改字符串对象的过程中,会产生很多字符串新的字符串对象,造成内存的浪费。
//验证String对象一旦创建,就不能改变(我们在上面的代码中对“123456789”这个字符串进行方法,其实都是生成了一个新的字符串,如果我们打印str1,那么它的结果还是123456789)
public class TestString {
public static void main(String[] args) {
String str="1234";
str.concat("456");//字符串的连接,这也是产生了一个新的字符串,只是没有任何的引用指向它。
System.out.println(str.replace("4","68"));//12368
System.out.println(str);//1234
}
}
通过练习得出一个结论,所有的看似对String对象修改的方法,其实本质上都没有修改源字符串,都是生成了一个新的字符串对象。这也会造成一个很大的缺点,会产生很多的字符串对象,造成内存的浪费。(这一点有点像Integer)一定要注意这个不能变是由两个原因导致的,一、由final修饰;二、对外没有提供修改的方法。
//疑问:是不是str被改变了??不是。str第一次指向“123” 第二次指向“345”,怎么验证呢?看下一段代码。
public class TestIntern{
public static void main(String[] args) {
String str="123";
str="345";
System.out.println(str);
}
public class TestIntern{
public static void main(String[] args) {
String str="123";
String s=str;//此时str和s都指向了“123”
//如果String对象不能改变,则s指向123,str指向456
//如果String对象可以改变,那么s和str都指向456
str="456";//这里str重新指向了“456”
System.out.println(s);//123 如果可以改变,则意味着s和str的结果都是456
System.out.println(str);//456
}
4.Java针对String 类的特殊的处理、针对缺点的弥补
String 对象的赋值方式就很特殊。String s = “123”;
我们说String对象由很多对象创建只用了一次就不用了,造成内存的浪费,可以想一下,对于不可变的对象,在Integer那里是怎么做的?是尽量复用相同的对象,给你创建好了,用就行了。那么String类的扣留机制就是尽量复用已经创建好的,内容相同的字符串对象。那么怎么复用?如何复用呢?把下面的代码理解了就可以了。看一下哪一种写法是让它尽量的复用我们已经存在的字符串对象,那么使用这种方式就可以了。双等号(==)是检测地址的,地址相同就代表着复用。
/**
*String类的扣留机制
* 尽量复用已经创建好的,内容相同的字符串对象。
*/
public class TestStringIntern{
public static void main(String[] args) {
String str="123";
String s=str;
str="345";
System.out.println(s);
System.out.println(str);
String s1="a";
String s2="b";
//s3直接指向方法区常量池中的"ab",s3存储的是"ab"在常量池中的地址。
//这种写法会创建0-1个对象。如果常量池中没有就添加一个,如果已经存在就直接指向。
String s3="ab";//这种赋值语句可以创建0-1个对象,如果常量池中有,就直接指向,如果没有,则把“ab”对象放在常量池中,它指向这个对象。
//编译器在编译期对下述的代码做了优化,将两个常量合并为"ab"
//因为"ab"已经存在于常量池中,所以s4也直接指向常量池中的"ab"
String s4="a"+"b";//这条语句没有创建对象,它直接指向常量池中的"ab"
//s5指向的是堆内存,堆内存中的对象地址
String s5=s1+s2;
//s6指向堆内存
String s6=new String("ab"); //这句代码下面有内存分析图
//这种情况会创建1-2个对象,堆内存中一定是创建了一个对象,
//如果常量池中没有abc,那么常量池中会添加一个abc;如果已经存在了,就不添加。
String s9="abc";
//如果常量池中包含了"ab",那么就直接返回常量池中的地址,
// 如果不包含"ab",那么就在常量池中添加"ab"。并返回常量池地址。//所以intern()方法一定是返回常量池地址的。
//该方法允许在运行区将字符串动态的添加到常量池。
String s7=new String(s1+s2).intern();
String s8="ab";
System.out.println(s3==s4);//true
System.out.println(s3==s5);//false
System.out.println(s3==s6);//false
System.out.println(s3==s7);//true
System.out.println(s3==s8);//true
}
}
那么s3、s4、s7、s8这样的写法都实现了字符串对象内容相同的复用,那么s5、s6这种写法就不建议使用了。这里我们解释一下为什么? 在运行期jvm给每一个java 的应用程序在方法区开辟了一块内存,用来存方法字符串常量,字符串常量池 string constant pool,该常量池由String类自己维护。所有的出现在程序中的字符串常量 “”(即用双引号扩起来的) 都会在编译期 就确定下来,到了运行期都会添加到常量池。常量池中的字符串对象的内容必须是唯一的。不能存在两个字符串对象具有相同的内容。
通过上面的代码,我们得出一个结论:以后创建字符串对象的时候,尽量使用String s = “123”;这种方式(因为创建的对象少),除非有特殊的要求才使用new 去创建。
说明:什么叫字符串常量呢?出现在程序中 的所用用双引号括起来的都叫字符串常量,例如上面代码中的"a",“b”,“ab” 而s1、s2是变量。

第四节StringBuffer、StringBuilder
1.特点:底层使用char[] value 实现。通过方法调用可修改它的长度和内容。该类提供了大量的修改value 内容的方法。(我们学StringBuffer主要就是学习这些方法)
2.StringBuilder 是在jdk1.5出现的。提供了和StringBuffer一致的API。该类的出现是为了在线程安全的情况下实现对StringBuffer的一个替代,来实现更高的效率。StringBuffer是线程安全的类,效率相对较低。StringBuilder是线程非安全的,效率更高。
在底层也是使用char value[] 数组来存的,char[]数组是继承父类里面的。先看一下源码:
| public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence{} |
|---|
| /*The value is used for character storage/ char[] value; |
| /**The count is the number of characters used.*/ int count; 指的是元素的个数 |
说明:这里的char[] value 没有用final修饰,那么这个value 就可以指向其他长度的char[] 数组了(可以理解成数组长度可变了)。并且提供了set、 get方法(也就是大量的提供了修改元素的方法)
/**
*StringBuffer的一些常用方法
*/
public class TestStringBuffer {
public static void main(String[] args) {
test1();
}
public static void test1(){
//对象刚刚创建,这个char数组就创建了,里面的只是默认值null
StringBuffer sb=new StringBuffer();
//在这里我们测一下刚刚创建出来的数组的长度是多少?
System.out.println(sb.capacity());//输出它的容积16
//length()是求它的有效的字符个数
System.out.println(sb.length());//输出字符个数0
//尾部添加
sb.append(1);//这个1在底层先转换为字符串(依赖于toString())再添加进去
//我们这个sb里面存的是字符序列,你里面添加对象的时候都要转化为字符串对象,那么怎么转呢?
// 调用toString(),我们没有重写,就用默认的
sb.append(new TestStringBuffer());//在这里调用了new TestStringBuffer()对象的toString()方法
//插入
sb.insert(1,true);//第一个参数是偏移量,第二个参数是想要插入的值
//delete删除
int index=sb.indexOf("@");//求出@的索引
sb.deleteCharAt(index);//括号里面是索引值
index=sb.indexOf(".");
sb.delete(index,sb.length());//删除一个区间,前闭后开的
//修改
sb.setCharAt(5,'_');//第一个参数:修改位置的索引;第二个参数:要修改的值。
//sb.setLength(6);//设置序列长度,超过的内容直接被截掉
System.out.println(sb.length());//8
System.out.println(sb.capacity());//82 当我们往里面插入内容的时候,当容量不够的时候,会进行扩容
//让长度和容量一致 //这个方法就是将空白的没有包含有效字符的删掉
sb.trimToSize();//trim是剪裁的意思,例如:当容量是82,有效数据是8时,会造成容量的浪费,这个时候为了让容量个数据长 度保持一致。
System.out.println(sb.length());//有效数据8个
System.out.println(sb.capacity());//容量是8
System.out.println(sb);//以上的操作都是从原字符串的基础上改的。
}
}
第五节 其他的常用类
1.java.lang.Runtime
Java运行时类,这个类在一个java程序中只有唯一的一个实例,而且该实例是由jvm创建的。如何得到它唯一的实例呢?是我们的应用程序和jvm之间的一个桥梁,通过该桥梁可以访问某些jvm的功能和属性。
import java.io.IOException;
/**
* 测试Runtime的一些用法
*/
public class TestRuntime {
public static void main(String[] args) throws IOException {
//得到实例的唯一方式
Runtime runtime=Runtime.getRuntime();
//访问JVM的某些功能
//返回JVM的可用内存和总内存
long l=runtime.freeMemory();
l=runtime.totalMemory();
//调用垃圾回收
runtime.gc();
//结束虚拟机
//runtime.exit(0);
//可以使用JVM去执行本地的程序
Process process=runtime.exec("notepad.exe E:\\ideaprojects\\javase\\oop1018\\src\\com\\sxt\\first\\TestRuntime.java");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//销毁程序
process.destroy();
}
}
2.Java.lang.System 系统工具类 都是静态方法
out:是System 类的静态成员变量。代表了我们标准的输出设备,控制台。该对象是在系统启动的时候进行初始化的。
in:是System 类的静态成员变量。代表了我们标准的输入设备,键盘。该对象是在系统启动的时候进行初始化的。
/**
* 测试System的一些用法
*/
public class TestSystem {
public static void main(String[] args) {
int[] arr={11,3,4,5,6,7};
int[] array=new int[3];
System.arraycopy(arr,1,array,0,3);
System.out.println(Arrays.toString(array));
//
long time=System.currentTimeMillis();
test();
long cost=System.currentTimeMillis()-time;
System.out.println(cost);
}
//此方法用于测试算法的优劣
static void test(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
3.java.lang.Math 数学工具类
/**
* 测试Math的一些方法方法
*/
public class TestMath {
public static void main(String[] args) {
System.out.println(Math.random());//[0.0-1.0)
System.out.println(Math.abs(-1));//输出1,此方法用于求绝对值
System.out.println(Math.PI);
System.out.println(Math.floor(1.1));//输出1.0,此方法用于向下取整
System.out.println(Math.ceil(1.1));//输出2.0,此方法用于向上取整
System.out.println(Math.round(4.4));//输出4
System.out.println(Math.round(4.5));//输出5
System.out.println(Math.sqrt(9));//输出3.0
System.out.println(Math.pow(3,4));//输出81,此方法表示几的几次幂
//弧度转为角度
System.out.println(Math.toDegrees(1));//57.29577
//角度转为弧度
System.out.println(Math.toRadians(180));//3.1415926
}
}
4.java.util.Random
这是一个专门用于求各种随机数的工具类。
import java.util.Random;
/**
* 测试Random类的一些方法
*/
public class TestRandom {
public static void main(String[] args) {
Random random=new Random();
//随机的int值(有可能是正值也有可能是赋值)
int i=random.nextInt();
//将随机得到的负数变为整数,一种方法是取绝对值,还有一种方法如下所示:
i >>>=1;//等价于i=i>>>1
int min=10;
int max=12;
//生成一个[min,max)之间的随机数
i=(random.nextInt()>>>1)%(max-min)+min;
System.out.println(i);
i=random.nextInt(10);//生成一个随机数[0,10)
System.out.println(i);
random.nextLong();
random.nextFloat();
random.nextDouble();
System.out.println(random.nextBoolean());
}
}
今日练习:
1:自定义方法:实现获得一个随机字符的功能(要求,随机字符必须是26个英文字符,大小写也随机)。
2:使用上面定义的方法,去获得20个随机字符,添加到一个StringBuffer对象中。并打印内容。然后实现将对象中的小写字符删除,并打印剩余的大写字符。
3.实现算法,对于任意给定的字符串,对该字符串求出统计的结果:只对字符有效
**
* 常用类练习
*/
public class Test1{
public static void main(String[] args) {
printUpperCase();
count("abcfagf");
}
//1:自定义方法:实现获得一个随机字符的功能(要求,随机字符必须是26个英文字符,大小写也随机)。
public static char randomChar(){
int num1=MyUtil.getRandomNumber(0,2);
int num2=MyUtil.getRandomNumber(65,91);
if(num1==0){
return (char)num2;
}else{
return (char)(num2+32);
}
}
//2:使用上面定义的方法,去获得20个随机字符,添加到一个StringBuffer对象中。并打印内容。
// 然后实现将对象中的小写字符删除,并打印剩余的大写字符。
public static void printUpperCase(){
StringBuffer sb=new StringBuffer();
for(int i=0;i<20;i++){
sb.append(randomChar());
}
System.out.println(sb);
//调用定义的delete方法
delete(sb);
System.out.println(sb);
}
//实现将对象中的小写字符删除,并打印剩余的大写字符。
public static void delete(StringBuffer str){
for(int i=0;i<str.length();i++){
if(str.charAt(i)>=97 && str.charAt(i)<=122){
str.deleteCharAt(i);
delete(str);
}
}
//System.out.println(str);
}
//实现算法,对于任意给定的字符串,对该字符串求出统计的结果:只对字符有效。
public static void count(String str){
StringBuffer sb=new StringBuffer(str);
int count=1;
char str1=sb.charAt(0);
for (int i = 1; i < str.length(); i++) {
if(str1==str.charAt(i)){
count++;
sb.deleteCharAt(i);
}
}
System.out.println(str1+"-"+count);
sb.deleteCharAt(0);
//System.out.println(sb);
if((sb.toString().length())>=1){
count(sb.toString());
}
}
}
//生成随机数的工具类
class MyUtil{
private MyUtil(){}
public static int getRandomNumber(int min,int max){
return (int)(Math.random()*(max-min)+min);
}
}
Java基础精讲
本文深入讲解Java中的Integer类、String类、StringBuffer类等核心概念,包括包装类的使用、自动装箱拆箱、字符串操作及性能优化技巧,适合Java初学者和进阶者阅读。
2万+

被折叠的 条评论
为什么被折叠?



