StringBuider:线程不安全,效率高
StringBuffer:线程安全,效率低;
用法举例:
class TWC
{
public static void main(String []args)
{
StringBuilder sb=new StringBuilder("小麻子爱吃粑粑");
System.out.println(Integer.toHexString(sb.hashCode()));
System.out.println(sb);
sb.setCharAt(2,'卷');
System.out.println(Integer.toHexString(sb.hashCode()));
System.out.println(sb);
StringBuilder cj =new StringBuilder();
for(int i=0;i<26;i++)
{
char tmp=(char)('a'+i);
cj.append(tmp);
}
cj.reverse();
System.out.println(cj);
System.out.println(cj.insert(0,'麻'));//可以实现链式调用,该方法最后返回自己;
System.out.println(cj.delete(1,3));//也可以链式调用
}
}
/*
结果:
1b6d3586
小麻子爱吃粑粑
1b6d3586
小麻卷爱吃粑粑
zyxwvutsrqponmlkjihgfedcba
麻zyxwvutsrqponmlkjihgfedcba
麻xwvutsrqponmlkjihgfedcba
*/
StringBuilder和StringBuffer陷阱:
public class Main
{
public static void main(String[]args)
{
long num1=Runtime.getRuntime().freeMemory();
long time1=System.currentTimeMillis();
String str8="";
for(int i=0;i<5000;i++)
{
str8+=i;
}
long num2=Runtime.getRuntime().freeMemory();//获取现在的时间
long time2=System.currentTimeMillis();//获取系统剩余的空间
System.out.println("String的占用时间"+(time2-time1));
System.out.println("String的占用空间"+(num1-num2));
long num3=Runtime.getRuntime().freeMemory();
long time3=System.currentTimeMillis();
StringBuilder str9=new StringBuilder("");
for(int i=0;i<5000;i++)
{
str9.append(i);
}
long num4=Runtime.getRuntime().freeMemory();
long time4=System.currentTimeMillis();
System.out.println("StringBuilder的占用时间为"+(time4-time3));
System.out.println("StringBuilder的占用的空间"+(num3-num4));
}
}
//将下面的替换上面的,可以感觉效率明显提高
/*
运行结果:
String的占用时间76
String的占用空间36684232
StringBuilder的占用时间为0
StringBuilder的占用的空间0
*/
时间类:
import java.util.Date;
class DateTest
{
public static void main(String[]args)
{//Date如果没有参数则在当前时间,如果是有参数,则创建的对象的时间是距离1970.1.1零点距离参数毫秒的时间,有时区不同
Date d=new Date(2000);
System.out.println(d);
System.out.println(d.getTime());//d距离1970。1.1零点获取毫秒
Date d1=new Date();
System.out.println(d.after(d1));
}
}
结果:
Thu Jan 01 08:00:02 CST 1970
2000
false
import java.text.*;
import java.util.Date;
class examTime
{//把时间对象按照格式字符串指定的格式转成相应的字符串;
public static void main(String[]args)throws ParseException
{//yyyy代表四位数的年份,mm代表两位数的月份,dd代表两位数的日期,hh表示小时,mm表示分,ss表示秒
DateFormat df=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");//按照格式转化;
String str=df.format(new Date(4000));
System.out.println(str);
//将字符串按照指定的格式转成相应的事件对象;
DateFormat sb=new SimpleDateFormat("S毫秒");//大写S表示的是毫秒;
Date date=sb.parse("1999毫秒");
System.out.println(date);
}
}
/*
运行结果:
1970-01-01 08:00:00
Thu Jan 01 00:00:01 CST 1970
*/
import java.text.*;
import java.util.*;
class Calendar11
{
//如果没有初始化的话就是在当前的时间下
public static void main(String[]args)
{//查看日期
Calendar calendar=new GregorianCalendar();
System.out.println(calendar);
int year =calendar.get(calendar.YEAR);
int month=calendar.get(calendar.MONTH);
int day=calendar.get(calendar.DATE);
int hour=calendar.get(calendar.HOUR);
int minute=calendar.get(calendar.MINUTE);
System.out.println("现在是"+year+"年"+month+"月"+day+"日"+hour+"时"+minute+"分");
//设置日期
calendar.set(Calendar.MONTH,3);//0~11;
//不要打印对象.MONTH等是常量不会改的;
System.out.println(calendar);//不可以直接打印
//日期的计算
Calendar c3=new GregorianCalendar();
c3.add(Calendar.MONTH,3);
System.out.println(c3);
//日期和时间的转化Date,Calendar
Date c4=c3.getTime();
Calendar ms=new GregorianCalendar();
ms.setTime(new Date());
}
}
Math类:
class Testmath
{
public static void main(String[]args)
{
//向上取整
System.out.println(Math.ceil(3.14));
//向下取整
System.out.println(Math.floor(3.85));
//四舍五入
System.out.println(Math.round(3.3));
//常用的常量E,PI;Math.E,Math.PI;
//分别表示数学中的自然数,圆周率;
//Math.sqrt,Math.abs,Math.pow都可返回浮点型
System.out.println("返回0~1之间的小数不包括1\n"+Math.random());
}
}
/*
结果:
4.0
3.0
3
返回0~1之间的小数不包括1
0.813373347319311
*/
File类:
import java.io.*;
import java.util.*;
class Test
{
public static void main(String[]args)throws IOException
{
File ff=new File("D:\\心累");
System.out.println(ff);//打印路径
ff.renameTo(new File("D:/小心心"));//修改文件名或者目录;
System.out.println(System.getProperty("user.dir"));//指的是当前项目文件夹;
//创建新的文件如果没有绝对路径指的是当前文件夹下的;
File f1=new File("gg.text");
f1.createNewFile();
System.out.println("文件是否存在"+f1.exists());
System.out.println("文件是否是目录:"+ f1.isDirectory());
System.out.println("文件是否是文件"+f1.isFile());
System.out.println("文件最后修改时间"+new Date(f1.lastModified()));
System.out.println("文件的大小:"+f1.length());
System.out.println("文件名"+f1.getName());
System.out.println("文件的目录路径"+ f1.getPath());
System.out.println("文件的目录绝对路径"+f1.getAbsolutePath());
//使用mkdir创建目录和使用mkdirs创建目录
//第一个只要有一个不存在目录不存在就不可以创建最终目录
File ft=new File("D:/声明");//创建失败
boolean flag=ft.mkdir();
System.out.println(flag);
//第二个没有都会帮你创建
File ftt=new File("D:/声明/创建");
boolean flag1=ftt.mkdirs();
System.out.println(flag1);//但是如果存在了就不会再创建了
}
}
/*
结果:
D:\心累
D:\IdeaTAT
文件是否存在true
文件是否是目录:false
文件是否是文件true
文件最后修改时间Sat Jul 08 16:57:09 CST 2023
文件的大小:0
文件名gg.text
文件的目录路径gg.text
文件的目录绝对路径D:\IdeaTAT\gg.text
false
true
*/
Random类:
import java.util.*;
class RandomTest
{
public static void main(String[]args)
{
Random rand=new Random();
System.out.println("随机生成0~1的double类型的数"+rand.nextDouble());
System.out.println("随机生成0~1的float类型的数"+rand.nextFloat());
System.out.println("随机生成int范围内的数"+rand.nextInt());
System.out.println("随机生成0~10之间的int类型的数据"+rand.nextInt(10));
//上面取的都是取左不取右边界;
}
}
枚举类:
枚举类里面的都是常量,避免使用枚举类的高级特性:
异常机制:Error和Exception,其中Exception分为编译时异常和运行时异常,编译时一场由两种解决方案:
try/catch处理:
可以用多个catch,如果有多个异常,用多个catch的时候一定要注意,子类在前,父类在后;
throw声明异常处理:
将问题抛给引用者:一般用关键字throws:
import java.io.*;
class test01
{
public static void main(String[]args)
{
FileReader reader=new FileReader("gg.text");
}
}
选择有红线的地方:
选择重点标记的地方:
操作之后的结果:
自定义异常:暂时不补充;
G-AABBCC)
这题也写了好久,先要关注几个点:首先它的数据很大,其次求素数,所以可以先将一定范围内的素数求出来,肯定不要求全部,这里差不多求到万为单位就可以了,因为就算是最小的也是将2*2*3,这样后面的最后一个才可以保证最大,然后计算:大概30万多就可以了;其实懂得了这个还不能做完这个题,我刚开始也是想到这里,最主要的在后面:在那个三重循环里面,①(一定要限制每一个数字的范围,)否则数太大会超过int的范围,然后是整个答案有错(我深受其害),说一下而为什么还会超过范围,这是由于求出30多万的数据只是在最坏的情况下,而且三位数有大小,一旦第一位也就是最小的超过了一定位数,算出来的答案就会错乱,应该和底层原理有关,刚开始我用longlong来装,也没用,也会超,所以要一开始就将它们的位数限制;根据一下计算我可以知道,第一位一定不可能超过1000,第二位不会超过10000,然后要记得在比n大的时候就break减少时间,②(还有在有很多数乘起来的时候有相同的用乘方,我刚开始直接乘算出来的结果总是错乱的)只有在这两点满足之后去做才不会有意外发生;
#include<stdio.h>
#include<math.h>
int d[400000];
int prime[400000];
int isprime(int a)
{
int j=0;
int k=0;
for(int i=2; i<=a; i++)
{
if(!prime[i])
{
d[k++]=i;}
for(int j=0;j<k&&d[j]<=a/i;j++)
{
prime[i*d[j]]=1;
if(i%d[j]==0)break;
}
}
return k;
}
int main()
{
int flag=0;
long long n;
int m=0;
int h=isprime(400000);
scanf("%lld",&n);
for(int i=0; i<h-2; i++)
{
if(d[i]>1000)break;
for(int j=i+1; j<h-1; j++)
{
if(d[j]>10000)break;
for(int k=j+1; k<h; k++)//有坑
{
if(pow(d[i],2)*d[j]*pow(d[k],2)<=n)//不要直接乘,数据爆破
{
m++;
}
else break;
}
}
}
printf("%d\n",m);
return 0;
}
还有不要线性思维以为一旦超过n就结束整个循环,即使三个已经是有序的,还是可能后面算出来的比前面的小,浅浅模拟一下就知道了。对了,数字太大记得欧拉筛。
H-Gap Existence)
题外话:之前写YES这种全是大写的写惯了,突然来一个有小写的就wa了好几发(看清题真的很重要)
我的思路是把他排好序,然后再从第一个①开始减,如果刚开始比他大就往后跳,相等就打印Yes,小的话就开一个小循环将该元素①和他后面的元素依次比较,如果相同或者大于x就break继续将这个元素①往后移;想法很美妙,首先时间超限,尽管不断改进,还是只有80%(最终版),其次,刚开始还没有考虑到只用后面的元素减前面的会如果x是负数则不成立,所以先要将x赋值为它的绝对值,后面看了一位前辈的博客,才得到的改进:
AT_abc296_c 题解 - Crazyouth 的垃圾场 - 洛谷博客 (luogu.com.cn)
我能做的就是解释一下大佬说不可以将tail和head放到循环里面head<tail做条件,由于x已经改变了绝对值,所以他们两个是要有先后顺序的,但是他们可以相等,如果刚开始两个比较大于x这时候就要将减数往前移,这时候它们的下标就已经相等了,所以可以添加条件tail>=head;其实不加也没关系,因为有tail<=n条件在tail不可能小于head;
H-Mismatched Parentheses)
本来括号匹配用的是栈,然后我用了两个,但是由于两个类型不一样,我就将整型转为字符型,+‘0’,之前听过-‘0’字符型转整型的,但是就是这个操作,我RE了五次,然后老老实实再写一个整数栈才过,所以提醒:整型转字符型千万别轻易加‘0’转,特别是在有数组的里面;
#include<stdio.h>
typedef struct
{
char base[200010];
int top;
}Stack;
int initStack(Stack &S)
{
S.top=0;
return 1;
}
int enStack(Stack &S,char e)
{
//if(S.top==MAXSIZE-1)
// return 0;
S.base[S.top++]=e;
return 1;
}
int deStack(Stack &S,char &e)
{
//if(S.top==0)return 0;
e=S.base[--S.top];
return 1;
}
void printStack(Stack S)
{
int p=0;
while(p!=S.top)
{
printf("%c",S.base[p++]);
}
printf("\n");
}
int s[200010];int head=0;
int main()
{
int n;
scanf("%d",&n);
char c;
Stack S;
int flag=0;
initStack(S);
char e;
scanf("%c",&e);
while((scanf("%c",&c))&&c!='\n')
{
int g=0;
if(c=='('){flag++;s[head++]=S.top;}
if(c==')')
{
if(flag)
{
flag--;
int h=s[--head];
S.top=h;
g=1;
}
}
if(!g)
enStack(S,c);
}
printStack(S);
}
喝下一碗心灵鸡汤之后要安心入睡哦:希望你一如既往的坚强, 站在迎着光的地方 ,活成自己想要的模样!!!