string是一个类,属于引用类型。
java中一切使用""引用的内容,都是这个类的实例,称字符串对象。
buffer:缓冲区
字符串定义后是一个常量,值不可更改。字符串实际是一个字符数组。
只引用最后赋的值。
频繁操作字符串,不能使用字符串拼接,效率低。建议使用StringBuilder类和StringBuffer类。
创建一个字符串对象 双引号“”赋值创建 通过构造方法创建public static void main(String[] args) { String str1=new String("12144"); String str2=new String("12144"); System.out.println(str1==syr2); //运行结果 false //两个变量的值虽然相同,但是存储的位置不同 }
编码格式://以下语句中,先在常量池中找“a”,不存在则创建“a”,new String()操作-->(堆中创建new StringBuilder()对象,又在字符串常量池中创建(定义)“b”,在堆中创建String对象,将“b”赋给该对象),再做拼接操作,将"a"和String对象拼接到StringBuilder()对象中,再将StringBuilder()对象保存到str5中。一共创建了4个对象:a、b、new String()、new StringBuilder()。
String str5="a"+new String("b")
String(bytes[] list,charsetName:"编码格式") 字符串与原始类型之间的转换 可变字符串
用于频繁改变String内容时的情况。
StringBuilder类非线程安全,适用于单线程环境
创建一个可变字符串对象创建一个可变字符串对象,默认没有值
构造方法创建:
StringBuilder sb = new StringBuilder ();
添加内容到可变字符串中,可以是任意内容
append(object obj):指定内容添加到末尾
删除[start,end)之间的字符: sb.delete(0,3);
删除指定索引的值: sb.deleteCharAt(0);
在指定索引上添加新内容 :sb.insert(1,"abc");
“*”替换[start,end)范围内的字符:sb.replace(1,4,"*");
判断一句话是否是回文体:
//创建一个不可变对象str String str = "上海自来水来自海上"; //创建一个可变对象 StringBuilder test = new StringBuilder("上海自来水来自海上"); //test.reverse()已经改变了test的值 test.reverse(); System.out.println(str); System.out.println(test); //调用toString()方法将改变后的test类型转换为String类型之后调用equals()方法比较两个对象是否相同 System.out.println(str.equals(test.toString()));
以上方法都是直接在原字符串上操作,原字符串会被影响。
StringBuffer类线程安全,适用于多线程环境,不得已情况下不建议适用
可变字符串与不可变字符串之间的转换比较String、StringBuilder、StringBuffer这三个类的区别
相同点:
-
都可用于表示或操作一个字符串
-
有公共的方法:如indexOf()、charAt()等
-
都是被final修饰的类,不能被继承
不同点:**
-
String定义的字符串是一个常量,不可变;StringBuilder、StringBuffer定义的是一个变量,可变。
-
String中的方法调用后,会创建字符串副本,不会影响原字符串;可变字符串对象调用的方法,直接操作原字符串,会影响。
-
StringBuilder是非线程安全的、StringBuffer是线程安全的,其中的方法使用synchronized修饰表示同步。
表示程序运行时对象,包含了程序运行环境相关信息。
不能通过new创建对象,因其构造方法时私有的。但是它提供了一个静态方法getRuntime(),可以获取一个Runtime类的对象。---单例模式
方法调用时传值问题如果参数是一个原始类型,当前方法中对该参数的所有操作,不会影响实参。
如果参数是一个字符串,当前方法中字符串“重新赋值”,实际是创建了一个新字符串对象,不会影响实参。
如果参数是一个引用类型,当前方法中又创建了一个新的对象,不会影响实参。
如果参数是一个引用类型,当前方法中直接对该参数进行操作,操作的就是该参数,会影响实参。
如果参数是数组(引用类型),当前方法中直接操作该数组,会影响实参。
总结:参数只有是引用类型(类、数组、接口),且方法中直接操作该参数,才会对实参有影响。
包装类装箱/拆箱
Date类用于表示日期时间的类。
构造方法Date() 创建当前瞬间的日期对象
常用方法
getTime() | 得到对应的Date对象指定的毫秒数 |
setTime() | 设置毫秒数 |
after(Date when) | 判断调用日期是否在when之后 |
before(Date when) | 判断调用日期对象是否在when之前 |
0-11表示1-12月。
simpleDateFormat类一个用于格式化日期的类。
calendar类(日历)是一个抽象类,无法直接创建对象,可通过该类的静态方法getInstance()获取该类的实例。
异常 exception:可以不用修改核心源码,通过额外的代码可避免exception的出现。
mismatch 不匹配
stackOverflow 堆内存溢出
error:错误,只能修改源代码。
处理异常 try-catch-finally语句try、catch、finally不能单独出现,try需要配合其中一个或两个才能使用。
finally除非在try中出现System.exit(0),否则一定会执行;如果try中出现return语句,不影响finally的执行,而且优先执行finally内的代码。
throws关键字可以让非运行时异常通过编译,定义方法时,声明可能抛出的异常,但不处理。
public void fun() throws InterruptedException{} //声明可能抛出的异常
throw和throws面试题- throws表示用于方法声明异常,使用时写在方法的小括号之后
- throw用于手动抛出异常对象。使用时写在{}中,通常用于满足某种条件时,强制中断程序。
手动通过throw关键字抛出异常,人为中断程序。
步骤
1、定义一个类,继承某个异常类:
若继承的是RuntimeException类,表示运行时异常,可以不处理异常对象
若继承的是非RuntimeException类,表示非运行时异常,必须处理异常对象
泛型一种规范,常用于限制集合中元素的类型。
用法:定义集合时,ArrayList
LinkedList list = new LinkedList<>();
list.offer("Object") | 添加尾节点 |
list.push("Object") | 添加头节点( 压栈) |
list.pop() | 得到并移除头结点(出栈) |
list.poll | 得到并移除头结点 |
list.peek() | 得到头结点,但不移除 |
保存的元素有序可重复,可以为null
set接口保存的元素无序不重复。可以为null,可通过索引获取对应的元素。
treeSet实现类不允许添加null,不允许添加重复元素(没有实现comparable)。
只能添加一种类型的对象且实现了comparable接口的对象
-
实现comparable接口后必须要重写compareTo方法。
-
每次调用添加,会自动调用该方法
Collections.shuffle(list),、 | 洗牌 |
Collections.reverse(list) | 倒序输出有序集合 |
Collections.reverse(list) | 对有序集合中的元素进行排序,但要求集合中的元素必须实现了Comparable接口。 |
Collections.max(list),Collections.min(list) | 得到集合中按CompareTo方法比较后的最大值最小值 |
Collections.fill(list,123) | |
Collections.swap(list,i,j) | 交换有序集合list某两个索引对应的元素。 |
Collections.rotate(list,int distance) | 将最后的distance个元素放到集合的最前面 |
Collections.replaceAll(List list,Object oldVal,Object newVal) | 将有序集合中的旧元素替换为新元素。 |
集合转换为数组:
Object[] 数组 = 集合对象.toArray()
HashMap实现类 文件流 流 (通道) file文件创建一个文件对象:
//方式一 File file = new File("文件路径及文件名"); //方式二 File parent = new File("路径"); File file = new File(parent,"文件名");
file.getName() | 得到文件名 |
file.getAbsolutePath() | 得到文件的绝对路径。 |
file.getPath() | 得到文件的相对路径(相对于当前java类出发)。 |
file.lastModified() | 查看文件最后一次修改的毫秒数。System.out.println(new Date(file.lastModified())),查看文件最后一次修改的时间。 |
file.length() | 查看文件所占字节大小。 |
file.isHidden() | 查看文件是否为隐藏文件 |
file.list() | 得到某目录下的第一层子文件的名称,返回String[ ] |
file.listFile() | 得到某目录下的第一层子文件对象,返回File[ ] |
file.delete() | 删除文件或空目录 |
file.renameTo(new File) | 移动源文件并对其重命名 |
一、按方向分
输入流:InputStream Reader 输出流:OutputStream Writer
作用:将硬盘中的数据读取到内存中 作用:将内存中数据写入到硬盘中
二、按类型分
字节流:InputStream OutputStream 字符流:Reader Writer
作用:适用于非文本类型,如图片、文件等的读写 作用:适用于文本类型,尤其txt格式文件的读写
总结:如果要将硬盘中某个txt文件中的字符读取到程序中,使用Reader;
如要将硬盘中的某个图片读取到程序中,使用InputStream。
fileReder字符输入流使用ready()方法不用再用-1验证,判断是否还有字符。
使用readLine()方法读取一行。
fileWriter按字符写入
fileWriter直接支持字符串的输入,但一定要调用flush(),否则不能写入。全部写完之后,再调用close(),保证内容写入成功。
构造方法 BufferedReader,BufferedWriter BufferedReader,使用它,必须先创建一个FileReader,这之前得先创建一个File对象。使用ready()方法不用再用-1验证,判断是否还有字符。
使用readLine()方法读取一行。
最后关闭 BufferedReader,br.close().
例如:
//覆盖 BufferedReader br = new BufferedReader(new FileReader(new File("c:/info.txt"))); //追加 BufferedWriter bw = new BufferedWriter(new FileWriter(new File("c:/info.txt"),true)); bw.newLine()//换行 流的分类 ObjectOutputStream对象输出流(序列化)
序列化:对象转换为文件的过程
序列化一个类,类必须实现Serializable接口
ObjectInputStream对象输入流(反序列化)反序列化:文件转换为对象的过程
BufferdReader读取文本文件,ObjectOutputStream将集合序列化为文件
转换流实际属于字符流,将一个字节流对象(...Stream)转换为字符流对象(...Reader / Writer)
转换流的使用OutputStreamWriter,字节输出流 --> 字符输出流
InputStreamReader,字节输入流 --> 字符输入流
如果只提供了一个字节流,又要发送文本时,就可以将字节流转换为字符流后发送文本。
网络编程 InetAddress类//InetAddress用于表示当前计算机所在网络地址的类: InetAddress localHost = InetAddress.getLocalHost() //根据IP地址创建一个IP对象 InetAddress ip =InetAddress.getByName("192.168.3.46") //服务器端套接字对象
ipconfig 查看IP地址
Socket类的对象表示网络中的一个端点
ServerSocket类的对象表示网络中的一个服务端点
总结:字节输出流(OutputStream)-->字符输出流(OutputStreamWriter)-->缓冲字符输出流(BufferedWriter)-->bw.writer("一句话"),此时就可以发送一句话了。
使用套接字对象可以实现两个端点之间发送文件。
多线程 实现多线程 一、继承Thread类 二、RunnableThread类(推荐)依然要创建Thread对象才能使用多线程,Thread(Runnable target)构造方法或者Thread(Runnable target,String name)构造方法.
//将new MyRunnableThread()包装成Thread类,才能调用start()启动线程 Thread t1 = new Thread(new MyRunnableThread(),"线程A"); t1.start(); 三、匿名内部类
解决多线程异步使用统一资源问题,fun()方法前加synchronized.
死锁解决方法:
一、fun方法中获取资源的顺序保持一致
二、在fun方法中让线程A和线程B获取A和B资源之前先获取第三个资源,并对其使用synchronized实现同步。