java语言基础知识
1:正则表达式:
含义 | 符合一定规则的字符串。 |
规则 | A:字符 x 字符 x ; \ \ 反斜线字符; \r 回车; \n 换行。 B:字符类:[abc] a、b 或 c(简单类。 [^abc] 任何字符,除了 a、b 或 c(否定)。 [a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内。[0-9] 0-9的数字字符。 C:预定义字符类 . 任何字符 \d 数字:[0-9]。\w 单词字符:[a-zA-Z_0-9]在正则表达式中可以组成单词的字符。 D:边界匹配器 ^ 行的开头 $ 行的结尾\b 单词边界 (出现的地方不能是单词字符。) E:数量词:X? X,一次或一次也没有 X* X,零次或多次 X+ X,一次或多次 X{n} X,恰好 n 次。 X{n,} X,至少 n 次。 X{n,m} X,至少 n 次,但是不超过 m 次9 |
功能 | A:判断功能 String -- public boolean matches(String regex)。 public String group()。 |
2、一些系统类
Random
Random用于产生随机数的类。
(1) 构造方法: Random:没有种子。每次产生的都是变化的。
Random(long seed): 有种子。种子一样,产生的随机数一致。
(2) 成员方法: int nextInt(): 返回int范围 int nextInt(int n): 返回[0,n)范围
System
系统类,提供了一些静态的功能供我们使用。
(1) 成员方法: A: public static void gc() 运行垃圾回收器。 B: public static void exit(int status)
终止当前正在运行的 Java 虚拟机。参数用作状态码;根据惯例,非 0 的状态码表示异常终止。
C: public static long currentTimeMillis()返回以毫秒为单位的当前时间。
D: public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
Date/DateFormat/Calendar
Date 日期类。可以精确到毫秒。A:构造方法 Date(), Date(long time)。B: 成员方法void setTime(long time) long getTime()。C: 如何得到毫秒值:Date --getTime() System -- currentTimeMillis();如何设置日期的毫秒值: Date -- Date(long time) Date -- setTime(long time)
DateFormat 对日期进行格式化和解析的类。
A: Date -- Stringpublic final String format(Date date)
B: String -- Datepublic Date parse(String source)
Calendar 日历类。把时间给分割成一个个的日历字段, 你可以通过get方法根据给定的日历字段获取对应的值。来组合一个完整的时间。
A: 根据给定的日历字段获取对应的值public int get(int field)。
B: 设置年月日: public final void set(int year,int month,int date)。
C: 根据给定的日历字段和值,来决定是加还是减去对应的值。public void add(int field,int amount)。
3:Collection
我们学习的是面向对象的语言,是以对象为主。如果想操作多个对象,就必须首先把这个多个对象给存储起来。到目前位置,我们仅仅只能使用数组来做这个事情。而数组有一个弊端,就是对象的个数必须是固定的。这个时候,java就提供了另外的一种容器:集合。
数组和集合的区别?
A: 数组 长度固定,元素可以是基本类型,也可以是引用类型。只能存储同一种数据类型。
B: 集合 长度可变,元素只能是引用类型。可以存储不同的数据类型。
Collection继承体系结构图:
Collection
————|--List
————————|--ArrayList
————————|--Vector
————————|--LinkedList
————|--Set
————————|--HashSet
————————|--TreeSet
分析:从具体到抽象 实现:从抽象到具体 学习:抽象使用:具体
Collection集合的功能概述
添加功能 | boolean add(Object e): //往集合中添加一个元素。 boolean addAll(Collection c): //往集合中添加一个集合的元素。 |
删除功能 | void clear(): //移除集合中的所有元素。 boolean remove(Object o): //移除集合中指定的一个元素。 boolean removeAll(Collection c): //移除集合中指定的一个集合的元素。 |
判断功能 | boolean contains(Object o) //判断集合中是否包含指定的元素。 boolean containsAll(Collection c) //判断集合中是否包含指定的一个集合的元素。 boolean isEmpty() //判断集合是否为空。 |
迭代器 | Iterator iterator() //用于获取集合中的元素。 |
长度功能 | int size() //获取集合中元素的个数。 |
交集功能 | boolean retainAll(Collection c) |
转换为数组 | Object[] toArray() //把集合转换为数组。 |
迭代器 A: 迭代器是集合的一种遍历方式。 B: 迭代器的使用步骤 a: 通过集合对象获取迭代器对象。b: 通过迭代器对象判断是否有元素。 c: 通过迭代器对象获取元素,并移动到下一个位置。
C: 每种具体的集合的迭代器的具体实现是在每个具体集合类中。以内部类的方式实现的。
List的特点
特点 | 元素有序(存储顺序和取出顺序一致),可重复。set元素无序,唯一。 |
特有功能 | 自己补齐 补齐方法的返回值类型和方法说明 A: 添加功能:add(int index,Object) 在指定的位置添加元素。 |
存储字符串并遍历 | a: 迭代器 b: 普通for(get()和size()结合使用)List集合存储自定义对象并遍历。 |
ListIterator的使用 | A:可以逆向遍历,但是要先正向遍历,一般不用。 B:并发修改异常的问题: 用迭代器迭代元素的时候,不能通过集合去改变集合。 解决方案: a: 集合遍历,集合修改。b: 列表迭代器遍历,列表迭代器修改。 |
List的3个儿子 | ArrayList: 底层数据结构是数组,查询快,增删慢。 线程不安全,效率高。 三个儿子我们到底使用谁呢:看需求:要安全吗?要:Vector不要:ArrayList或者LinkedList查询多:ArrayList增删多:LinkedList。什么都不知道,就用ArrayList。 |
4:泛型
一种把明确数据类型的工作推迟到创建对象或者调用方法的时候才去明确的特殊的数据类型。
默认情况下,泛型指的是Object类型。泛型的格式: <数据类型>
泛型的好处:A:优化了程序设计,解决了黄色警告线问题。B:把运行时期的异常提前到了编译期间。C: 避免了强制类型转换。
泛型的弊端: 用泛型限定了集合以后,集合中只能存储同一种数据类型。
泛型在什么时候用 看API,如果看到了<>,就说明这里要使用泛型。 一般来说,就是在集合中用。
集合的小问题:A:集合可以存储不同类型的元素,在遍历的时候,给出不同的判断即可。
Object obj = it.next();
if(obj instanceof String) {
...
}else if(obj instanceof Integer) {
}
B:集合中存储的基本类型,其实存储的不是基本类型,而是对应的包装类类型。
泛型类
class Demo<QQ> {
public void show(QQ qq) {
...
}
}
泛型方法
class Demo {
public <T> void method(T t) {
...
}
}
泛型接口
interface Inter<QQ> {
void show(QQ qq);
}
//方式1
class InterImpl implements Inter<String> {
public void show(String s){
}
}
//方式2
class InterImpl<QQ> implements Inter<QQ> {
public void show(QQ qq){
...
}
}
5:增强for
(1) 格式: for(Collection集合或者数组中的元素的数据类型 变量 : Collection集合或者数组的名称) {
使用变量即可。这个变量其实就是集合或者数组中的元素。
}
(2) 好处: 简化了集合或者数组的遍历。 (3) 把以前集合的案例用增强for改进遍历。
ArrayList<String> array = new ArrayList<String>();
array.add("hello");
array.add("world");
array.add("java");
for(String s : array) {
System.out.println(s);
}
6: Set
(1) Collection 下List 有序,可重复。Set 无序,唯一。
(2) HashSet :如何保证元素唯一性的底层数据结构是哈希表(散列表)。具体的是由一个元素是单向链表的数组组成。
它依赖于两个方法:hashCode()和equals()方法。执行顺序:先判断hashCode()是否相同,如果相同继承执行equals()方法,看其返回值:true:元素重复,不存储。false:元素不重复,存储。如果不同存储。
注: 看到HashXxx结构的集合就要知道被该集合存储的元素要重写hashCode()和equals()方法。而且是自动生成的。
(3) TreeSet 底层数据结构是二叉树。
如何保证元素的唯一性的, 根据比较的返回值是否是0来决定。
如何保证元素的排序的呢 A:自然排序 元素具备比较性让集合中被存储的元素所属的类实现Comparable接口。 B:比较器排序 集合具备比较性,在创建集合对象的时候,让构造方法接收一个Comparator接口的子类对象。
(4) LinkedHashSet底层由链表和哈希表组成。由链表保证有序。由哈希表保证唯一。
集合的遍历方式:Collection 迭代器,增强for。List 普通for
Set:A: 迭代器,增强for可以看成是一种方案。B: 一般来说,仅仅是为了遍历,我们选择增强for。C: 如果在遍历的时候,要使用到索引,必须使用普通for。
7:map
Map集合 | Map集合存储是键值对形式的元素。 |
Map和Collection集合的区别 | A: Map集合存储的是键值对形式的元素。 Collection集合存储的是单个的元素。 B:Map集合的键是唯一的。 Collection的儿子Set集合元素是唯一的。 C:Map集合的值是可以重复的。 Collection的儿子List集合的元素是可以重复的。 |
Map集合的功能 | A: 添加功能:V put(K key,V value) //如果键不存在,就是添加功能。如果键存在,就是修改功能。返回的是被修改前的值。 |
Map集合的遍历 | 通过键找值 a: 获取所有键的集合。keySet()。b: 遍历键的集合,得到每一个键。增强for。c: 根据键去map集合中找值。get(K key)。 通过键值对对象找键和值:a: 获取所有键值对对象的集合。entrySet()。b: 遍历键值对对象的集合,得到每一个键值对对象。增强for。c: 根据键值对对象获取键和值。getKey(),getValue()。 |
Hashtable和HashMap的区别 | A:HashMap 线程不安全,效率高。允许null键和null值。 B:Hashtable 线程安全,效率低。不允许null键和null值。 |
Collections工具类的使用。
(1) Collections是针对集合进行操作的工具类。
(2) Collection和Collections的区别
A: Collection 是集合的顶层接口,定义了集合中的共性功能。
B: Collections 是针对集合进行操作的工具类。提供了排序,查找等功能。
Collections常见的功能:A: 排序; B: 二分查找;C: 最大值 ; D: 反转;E: 随机置换
8 :异常
(1) 程序出现的不正常的情况。
(2) 异常的继承体系结构:
Throwable
————|--Error 严重的问题,一般我们解决不了。
————|--Exception
——————|--RuntimeException运行时期异常,这种问题一般要修正代码。
——————|--非RuntimeException编译时期异常,必须进行处理,否则代码不能够通过。
JVM针对异常的默认处理方案:
异常处理基本格式 | try...catch...finally JDK7的新特性:这个要求都是平级关系。 |
变形格式 | try...catch... try...catch...catch... try...catch...finally... try...catch...catch...finally...try...finally... 针对一个try多个catch的情况:父异常必须放最后。 |
throws | 后面跟的是异常类名。位置:在方法的()后面。注: 能try...catch就不要throws。 |
编译时期异常和运行时期异常的区别 | A:编译时期异常 必须进行处理的。B:运行时期异常 可以处理,也可以不处理。 |
throws和throw的区别 | A:throws 位置:在方法()后面,跟的是类名。 如果后面根据的是RuntimeException及其子类,那么,该方法可以不用处理。 如果后面根据的是Exception及其子类,那么,必须要编写代码进行处理,或者调用的时候抛出。 B:throw 位置:在方法中,跟的对象名称。 如果方法中,有throw抛出RuntimeException及其子类,那么,声明上可以没有throws。 如果方法中,有throw抛出Exception及其子类,那么,声明上必须有throws。 |
自定义异常 | 只需要继承自Exception或者RuntimeException。提供构造方法即可 |
默认情况下,会把异常的类名,原因,及错误出现的位置输出在控制台。并从这个地方终止程序运行。
9: file
IO流操作最主要的作用就是上传文件和下载文件。 而File类是java提供给我们用来表示文件的类。
File的构造方法 | A: File file = new File("d:\\a.txt"); B: File file = new File("d:\\","a.txt"); C: File file = new File("d:\\"); File file2 = new File(file,"a.txt"); | |
File类的常见功能 | 创建功能创建文件 | public boolean createNewFile():如果文件存在,就不创建。否则,创建。 |
创建文件夹 | public boolean mkdir():如果文件夹存在,就不创建。否则,创建。 | |
创建多级文件夹 | public boolean mkdirs():如果多级文件夹存在,就不创建。否则,创建。 | |
删除文件或者文件夹 | public boolean delete() 。 | |
重命名功能 | public boolean renameTo(File dest):如果路径相同,就是改名。如果路径不同,就是剪切。 | |
判断功能 | public boolean canRead() //是否可读 public boolean canWrite() //是否可写 public boolean isDirectory() //是否是文件夹 public boolean exists() //是否存在 | |
获取功能 | public String getAbsolutePath() //获取绝对路径 public String getPath() //获取相对路径 public String getName() //获取名称 public long length() //获取文件字节数 public long lastModified() //获取最后一次修改时间的毫秒值 | |
高级获取功能 | public String[] list() //获取指定目录下的所有文件或者文件夹的名称(String)数组。 public File[] listFiles() //获取指定目录下的所有文件或者文件夹的文件(File)数组。 | |
带过滤器的高级获取功能 | public String[] list(FilenameFilter filter): 例获取指定目录下指定后缀名的文件的名称。 |
10、递归、IO流
递归:
方法定义中调用方法本身的现象。例:老和尚给小和尚讲故事。
递归的注意事项:A: 递归一定要有出口,否则就是死递归。B: 递归的次数不能太多,否则内存溢出。C: 构造方法不能递归使用。
递归解决问题的基本思想:A: 分解和合并。B: 找哪些东西 出口与规律
递归的题目:1: 递归求阶乘; 2: 兔子问题; 3: 递归输出指定目录下指定后缀名的文件绝对路径;4: 递归删除带内容的目录
IO流
IO流的作用 | 上传文件和下载文件。 上传文件: 数据源:本地 目的地:服务器 下载文件: 数据源:服务器目的地:本地 | |
IO流的分类 | A: 流向 输入流-读取数据输出流-写出数据 B: 数据类型:字节流:字节输入流、字节输出流。字符流:字符输入流、字符输出流。 一般来说,如果没有说明按照哪种类型分,指的是按照数据类型分。 | |
字符流/字节流 | 如果一个要操作的文件,通过记事本打开并能够读懂其内容,就可以考虑使用字符流。否则,就使用字节流。什么都不知道,就用字节流。 | |
IO的基类及具体类 | 字节流 | 字节输入流:InputStream、FileInputStream。 字节输出流:OutputStream、FileOutputStream。 |
字符流 | 字符输入流:Reader、FileReader。 字符输出流:Writer、FileWriter。 | |
FileWriter写数据的步骤及代码体现 | 步骤: A:创建字符输出流对象。B:调用write方法。C:释放资源 代码体现: FileWriter fw = new FileWriter("fw.txt"); fw.write("hello,io"); fw.close(); | |
FileReader读数据的步骤及代码体现 | 步骤:A:创建字符输入流对象。B:调用read方法,并把数据显示在控制台。C:释放资源。 |
FileReader fr = new FileReader("fr.txt");//方式1:一次读取一个字符
int ch = 0;
while((ch=fr.read())!=-1) {
System.out.print((char)ch);
}
//方式2:一次读取一个字符数组
char[] chs = new char[1024];
int len = 0;
while((len=fr.read(chs))!=-1) {
System.out.print(String.valueOf(chs,0,len));
}
fr.close();
字节流继承体系 | InputStream——FileInputStream、OutputStream、FileOutputStream |
字符高效流 | BufferedReader 、BufferedWriter。 |
字节高效流 | BufferedInputStream、BufferedOutputStream。 |
字符高效流的特殊功能 | BufferedReader、String readLine()。BufferedWriter 、void newLine()。 |
IO流的使用:
文本文件的复制:9种。 字节流:4种; 字符流:5种。 二进制流数据的复制:4种。转换流:(1)键盘录入写到文本文件。用Scanner实现。(2)用System.in录入数据,写到文本文件。BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 理解:从字节到字符; 使用:从字节到字符(3)把文本文件的数据,用System.out写到控制台BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); 理解:从字符到字节
使用:从字节到字符
打印流:(1)打印流仅仅是用来写数据的,没有读取数据的。(2)打印字节流 PrintStreamSystem:
public static final PrintStream out。
System.out.println(); 打印字符流 PrintWriter (3) 特点:A: 可以把任意类型的数据写到文本文件。B: 如果启动了自动刷新,在调用println()的方法的时候,可以自动刷新,并换行。C: 可以直接对文件进行操作。问题:哪些流可以直接对象文件进行操作。看API,流的构造方法,如果可以同时有File和String类型的参数,就可以。
BufferedReader br = new BufferedReader(new FileReader("a.txt"));
PrintWriter pw = new PrintWriter(new FileWriter("b.txt"),true);
String line = null;
while((line=br.readLine()) != null) {
pw.println(line);
}
pw.close();
br.close();
11:字符编码/Properties/序列化和反序列化流
字符编码:
编码表:由字符及其对应的数值组成的一张表。
常见的编码表: ASCII ISO-8859-1gb2312gbk utf-8
编码问题:A:IO流中的编码问题。B:String类中的编码问题,统一编码最好。
Properties
(1)是键值对形式的属性列表。是Map体系的一个集合类。 可以和IO流进行结合使用。
(2)例:A:作为Map集合的使用。B:作为集合的特有功能使用:a: setProperty(String key,String value)。b: getProperty(String key) stringPropertyNames()。
C: 和IO流结合使用:a: load() 把文件中的数据加载到集合中;b: store() 把集合中的数据存储到文件中
序列化和反序列化流
(1)序列化:把对象按照流一样的方式存储到文件中或者在网络中传输。 简记:把对象按照流一样操作。
反序列化:把文件中或者网络中的流数据还原成对象。 简记:流数据还原对象。
(2)对象怎么才能实现序列化,让对象所属的类实现序列化接口。
(3) 看到一个类实现了序列化接口,就要知道,该类的对象可以被序列化流进行操作。将来还可以通过反序列化流还原。如果想在序列化后,对java文件做一些简单的改动,不影响以前写过的数据,那么,就应该在java文件中给出固定的序列化id值。而且,这样做了以后,还可以解决黄色警告线问题。
其他的几个了解的流对象
(1) DataOutputStream/DataInputStream
可以把基本数据类型的数据写到文件,也可以还原为基本的数据类型的数据。
只不过,要注意还原时候的顺序和写的顺序要一致。
(2) ByteArrayOutputStream,ByteArrayInputStream。(3) CharArrayWriter, CharArrayReader
12:多线程、网络编程
1)多线程
应用程序有多条执行路径。进程:正在运行的应用程序。线程:应用程序的执行路径,执行单元。多线程:一个应用程序有多条执行路径。实现方案:A: 继承Thread类;B: 实现Runnable接口
线程的随机性原理: CPU在多个程序间做着高效的切换来执行程序的。
线程的生命周期: 新建 -- 就绪 -- 运行 -- 死亡运行 -- 阻塞 -- 就绪
线程安全问题的产生及解决:a: 多线程环境;b: 是否有共享数据;c: 共享数据是否被多条语句操作;
解决方案: a: 同步代码块;b: 同步方法;c: JDK5以后的Lock锁。
同步的锁对象: 代码块:任意对象 方法:this静态方法:类名.class
线程间的通信: 不同种类的线程针对同一个资源的操作。
进程:正在运行的应用程序,系统会为其分配空间。 每个进程具备独立的空间。
线程:应用程序的执行单元,执行路径。 线程共享同一个进程的资源。
同步代码块:
synchronized(锁对象) {
需要被同步的代码。
}
A: 锁对象可以是哪些:Object的对象。这个锁对象可以是任意对象。但一定要注意多个线程必须使用的是同一个锁对象。
B: 需要被同步的代码是哪些:共享数据共享数据是否有多条语句操作。
2)网络编程
用编程语言来实现计算机的资源共享和信息传递。
计算机网络:多台独立的计算机用网络通信设备连接起来的网络。实现资源共享和数据传递。
网络通信的三要素:A: IP地址计算机在网络中的唯一标识。现在使用的是:"点分十进制"
B: 端口 应用程序的的标记。C: 协议通信的规则。
UDP: 不建立连接,数据打包传输,数据有限制,数据不可靠,速度快。
TCP: 建立连接,数据无限制,数据可靠,速度慢。
1、UDP发送和接收数据:先开启谁都无所谓。
步骤:1:创建发送端的Socket服务对象。:2:创建数据并把数据打包。3:发送数据。 4:释放资源。
代码体现
DatagramSocket ds = new DatagramSocket();
byte[] bys = "udp,你好".getBytes();
DatagramPacket dp = new DatagramPacket
(bys,bys.length,InetAddress.getByName("113.255.218.251"),12345);
ds.send(dp);
ds.close();
接收端:
步骤:1:创建接收端的Socket服务对象。2:创建数据包。3:接收数据。4:解析数据。5:释放资源。
DatagramSocket ds = new DatagramSocket(12345);
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys,bys.length);
ds.receive(dp);
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(),0,dp.getLength());
System.out.println(ip+"---"+data);
ds.close();
2、TCP发送和接收数据必须先开启服务器。
步骤: 1:创建客户端Socket对象。2:获取输出流。3:写数据。 4:释放资源。
Socket s = new Socket("113.255.218.251",12345);
OutputStream os = s.getOutputStream();
os.write("tcp,我来".getBytes());
s.close();
服务器端:步骤:1:创建服务器Socket对象。2:监听客户端连接。3:获取输入流。4:读取数据。5:释放资源。
ServerSocket ss = new ServerSokcet(12345);
Socket s = ss.accept();
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);
String data = new String(bys,0,len);
System.out.println(data);
s.close();
ss.close();