Object类
java.lang.Object类是所有类的父类。
Object类定义了“对象”的基本“行为”,被子类继承这些行为。
万事万物皆对象。
一个类定义的时候,没有使用extends继承某个特定父类,那么该类的父类就是Object.
Object类的toString方法
Object类中的toString方法,用于返回对象成员变量的字符串表示。
Object类中的toString方法的定义:
publicString toString() {
return getClass().getName() +"@" + Integer.toHexString(hashCode());
}
所有java类都有toString方法,通常会要求根据需要重写toString方法,返回更有意义的字符串。
System.out.println(obj) 等价于System.out.println(obj.toString())
Object类的equals方法
Object类的equals方法,用于判断对象是否相等。
Object类equals方法的定义:
自己和某个对象进行比较。
public boolean equals(Object obj) {
return (this == obj);
}
子类中可以根据实际需求,自定义比较规则,然后重写equals方法。
一般情况下,重写equals方法是为了比较两个对象的内容是否相等,比较方法是:判断两个对象是否为用一个对象,如果是同一个,再比较两个对象的值。
String
String的不可变性
java.lang.String中封装的是字符串序列。
String在内存中采用Unicode编码方式,一个字符两个字节的定长。
String对象创建之后,这个对象的内容(即对象中的字符串序列不可变)不可变化。
Stringstr = “abc”;
str = str.toUpperCase(); // 创建了新的字符串对象“ABC”,str指向新对象。
// 引用指向的对象变了, 原来的对象“abc”不变。
System.out.println(str);// “ABC”
常量池
java中可以使用直接量,创建字符串对象。
String str = “hello world.”;
出于性能的考虑,jvm会将这些字符串字面量对象,保存在常量池中,对于重复出现的字符串直接量,jvm优先在缓存中查找,如果存在就直接返回该对象。
String str1 = “nice to meet you .”;
String str2 = “niceto meet you .”;
System.out.println(s1 == s2) ;//true.
String str3 = new String(“niceto meet you .”);
System.out.println(s3== s2) ;// false.
String的equals方法
String类中重写了equals方法,规则为:两个字符串的字符串序列相同,那么equals为true.
String类中定义了equalsIgnoreCase,忽略大小写比较。
String的equals方法源码
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
集合
Collection
collection接口是集合的父接口
它的常用方法
List和Set
List和Set都实现了Collection接口,
List接口下有 ArrayList 和 LinkedList 类(比较常用)
Set接口下有 HashSet 和 TreeSet类
List是一个有序的 集合,它能保证数据的添加顺序(基于数组来实现的),输出数据的顺序就是数据添加的时候的顺序
Set是无序容器,它就像是把数据全部装入一个袋子里面,放入时无法保证数据的存储顺序,TreeSet通过Comparator 或 Comparable 维护了一个顺序
添加重复对象
List允许添加多个重复的对象,数据不唯一
Set不允许重复,数据唯一,添加的重复元素将会被覆盖
添加null
List中可以添加多个null 元素
Set只允许添加一个null 元素
常用的实现类
List接口常用的实现类有 ArrayList 、LinkedList 和 Vector,其中ArrayList最常用,数据根据索引的高速查询
LinkedList:在一些 插入、删除元素的场合较为常用
Vector:和 ArrayList 基本没什么区别,就是Vector是线程安全的
Set接口常用的实现类:HashSet、LinkedHashSet以及TreeSet
最流行的是 基于 HashMap实现的 HashSet
TreeSet 还实现了 SortedSet 接口,因此 TreeSet 是一个根据其 compare() 和compareTo() 的定义进行排序的有序容器
HashMap和TreeMap
HashMap直接实现了Map,而TreeMap则是实现了NavigableMap接口,而这个NavigableMap接口拓展了SortedMap接口,SortMap接口又拓展了Map接口。所以说TreeMap是有序的,HashMap是无序的。
总结
1、HashMap无序,TreeMap有序。
2、HashMap覆盖了equals()方法和hashcode()方法,这使得HashMap中两个相等的映射返回相同的哈希值;
TreeMap则是实现了SortedMap接口,使其有序。
3、HashMap的工作效率更高,而TreeMap则是基于树的增删查改。更推荐使用HashMap。
4、HashMap基于数组+链表+红黑树(jdk1.8之后)实现,TreeMap是基于红黑树实现。
5、两者都不是线性安全的。
Exception类
java异常结构中定义有Throwable, Exception 和 Error 是其派生的两个子类。其中Exception表示由于网络故障,文件损坏,设备错误,用户输入非法等情况导致的异常,而Error表示java运行时环境出现的错误,例如jvm内存资源耗尽。
异常出来就是当异常发生的时候妥善地终止程序,避免灾难性后果的发生,具体的操作通常包括;
通知:向用户通知异常的发生。
恢复:保存重要的数据,恢复文件, 回滚事务等
退出:以更好的方式结束程序的运行
try...catch...语句
•try{...}语句包裹了一段代码,该段代码就是捕获异常的范围。
•在执行try语句块的过程中,该段代码可能会抛出一种或多种异常,catch语句块可以分别对不同的异常做处理。
•如果try语句块没有发生,那么所有的catch语句都被忽略,不被执行。
•catch语句块中是对异常处理的代码,不同的异常,可以多个不同的catch语句块。
•当由多个catch语句的块的是,应该先捕获小类型的异常,或捕获大类型的异常。
throw语句
•当程序发生异常,不能处理的时候,会抛出对应的异常。
•可以通过throw 语句 ,将异常抛出,那么被抛出的异常,可以让其他代码来捕获这个异常。如果需要自行抛出异常,需要使用“throw”关键字,并且要创建出抛出的异常类的对象。
throw new XXException();
•类中有很多方法,当在类中的方法中使用到了throw 语句抛出了异常,那么在这些方法的声明过程中,需要使用throws 关键字,声明该方法抛出的异常。
public void add() thows XXExcedption{
// code
}
•如果在方面声明的时候,使用throws抛出了异常,那么在调用方法的时候,就需要捕获异常,或者继续抛出异常。
finally语句
•finally语句为异常处理提供一个统一的出口,使得在控制流程转到其他程序其他部分之前,能够对程序的状态做统一管理。
•无论try语句块中是否有异常,finally语句块的内容都会被执行。
•通常在finally语句块中完成一些必须要执行的代码。比如: 文件的关闭,数据库的关闭等。
IO流
IO,即in和out,也就是输入和输出,指应用程序和外部设备之间的数据传递,常见的外部设备包括文件、管道、网络连接。
Java 中是通过流处理IO 的,那么什么是流?
流(Stream),是一个抽象的概念,是指一连串的数据(字符或字节),是以先进先出的方式发送信息的通道。
当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接。类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流。这时候你就可以想象数据好像在这其中“流”动一样。
一般来说关于流的特性有下面几点:
先进先出:最先写入输出流的数据最先被输入流读取到。
顺序存取:可以一个接一个地往流中写入一串字节,读出时也将按写入顺序读取一串字节,不能随机访问中间的数据。(RandomAccessFile除外)
只读或只写:每个流只能是输入流或输出流的一种,不能同时具备两个功能,输入流只能进行读操作,对输出流只能进行写操作。在一个数据传输通道中,如果既要写入数据,又要读取数据,则要分别提供两个流。
IO流分类
FileInputStream、FileOutputStream
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class FileInputStreamDemo {
public static void main(String[] args) {
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream("C:\\Users\\86133\\Desktop\\abc\\def.txt");
byte[] b = new byte[100];
fileInputStream.read(b);
String str = new String(b);
System.out.println(str);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
对象序列化
将Object转换为byte序列,就是序列化,反之将byte序列转换为Object就是反序列化。
对象序列化的目的,是为了将对象,以byte流的方式存储。
使用writeObject(Object)/readObject()进行序列化和反序列化
ObjectInputStream ois ;
ois.readObject();
ObjectOutputStream oos ;
oos.writeObject(obj);
线程
原理
java程序支持多线程,并且java中的多线程处理较为简单。
一般操作系统都支持同时运行多个任务,一个任务通常就是一个程序,每个运行中的程序被称为进程,当也给程序运行时候,内部可能包含多个顺序流执行,每个顺序执行流就是一个线程。
Thread类
Thread类代表线程类型
任何线程对象都是Thread类(子类)的实例
Thread类是线程的模板(封装了复杂的线程开启等操作,封装了操作系统的差异性等)
只要重写run方法,就可以实现具体线程。
public class TestThread{
public static void main(String[] args) {
Thread t2 = new AskThread();
t2.start();
Thread t1 = new AnswerThread();
t1.start();
}
}
class AskThread extends Thread{
@Override
public void run() {
for (int i=0;i<100;i++){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("吃了吗");
}
}
}
class AnswerThread extends Thread{
@Override
public void run() {
for (int i=0;i<100;i++){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("我吃了");
}
}
}
Runnable实现线程
创建一个类,实现Runnable接口, 重写run 方法
以实现了Runnable接口的类的实例,作为创建Thread类的参数。
public class TestThread1 {
public static void main(String[] args) {
Thread thread = new Thread(new B());
thread.start();
}
}
class A{}
class B extends A implements Runnable{
@Override
public void run() {
System.out.println("hello");
}
}
线程中的内部类
public class TestThread2 {
public static void main(String[] args) {
Thread thread1 = new Thread(){
@Override
public void run() {
for (int i=0;i<100;i++){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("试衣服");
}
}
};
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i=0;i<100;i++){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("wo试衣服");
}
}
});
thread1.start();
thread2.start();
}
}
线程的生命周期
synchronized关键字
多个线程并发读写同一个临界资源的时候,会发生“线程并发安全问题”,使用同步代码块,解决并发安全问题
synchronized可以修饰方法,表示整个方法修的全部内容需要同步。
synchronized(同步监视器){ // .... } ,同步监视器一般是一个对象。
尽量减小同步范围,提供并发的效率。
CS架构——客户端&服务器端
在C/S模式下,客户向服务器端发出请求,服务器端接收到请求之后,提供相应的服务。
客户端部分: 每个用户都有自己的客户端,负责发送请求。
服务端部分: 多个用户共享一个服务器,处理每个客户端的请求。
Socket类
核心api
ServletSocket类
核心api
案列
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
private ServerSocket server;
public Server() throws IOException {
System.out.println("开始初始化");
server = new ServerSocket(9999);
System.out.println("初始化成功");
}
public void start(){
while (true){
System.out.println("等待客户端的连接");
try {
Socket socket = server.accept(); //阻塞方法
InetAddress inetAddress = socket.getInetAddress();
String hostAddress = inetAddress.getHostAddress();
int port = socket.getPort();
System.out.println(hostAddress+":"+port+"连接成功");
//流的使用
InputStream inputStream = socket.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader br = new BufferedReader(inputStreamReader);
String s = br.readLine();
System.out.println(hostAddress+":"+port+"说:"+s);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException {
Server server = new Server();
server.start();
}
}
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class Client {
private Socket socket;
public Client() throws IOException {
System.out.println("开始连接服务器");
socket = new Socket("localhost",9999);
System.out.println("服务器连接成功");
}
public void start() throws IOException {
OutputStream outputStream = socket.getOutputStream();
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
PrintWriter printWriter = new PrintWriter(outputStreamWriter);
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
printWriter.write(s);
printWriter.flush();
printWriter.close();
}
public static void main(String[] args) throws IOException {
Client client = new Client();
client.start();
}
}
总结
这段时间学习的集合,异常等都是用的比较多的,前期也学习过这些,这次学下来还是有写概念性的东西记不住,比如什么时候该用List集合,什么时候用Set集合,这些下来还要多看看,多做一点题。还有线程这一块,需要多多练习一下。