不全面,只是学习笔记的汇总,记了一些我觉得重点的。
细碎基础:
Java全面支持Unicode编码。
类、方法、变量名以$,字母(Unicode字符集),下划线开头,后面的可以是数字,字母,下划线。
如果我们没有手动初始化成员变量,系统会自动初始化。初的规则如下:
数值:0,0.0,0L 布尔:false char:\u0000 引用类型:null
程序以public static void main(String[] args){}函数作为程序入口。
final:
修饰变量:常量(命名规范:全部大写,多个单词之间通过下划线隔开)
修饰方法:不能被重写
修饰类: 不能被继承
二进制数可以用_分隔表示 int a = 0b0000_0000_0000_0000_0000_0000_0000_0011;
数值前有0默认是八进制
equals比较内容是否相等,==比较是否是同一个对象,instanceof 判断对象类
finalize 不是析构函数,即使对象的finalize运行了,不能保证该对象被销毁。要实现一些保证对象彻底被销毁时的动作,只能依赖于java.lang.ref里面的类和GC交互。
//建议系统进行垃圾回收
System.gc();
Runtime.getRuntime().gc();
for (int u : list) // forEach语法
System.out.println(u);
package:
package必须位于非注释行第一句。
包名:域名倒着写
import:引入外部的类
import 重名时其中一个使用完整引用即可
import static :导入类的静态属性
函数使用可变参数 ... 读取为数组
JVM内存模型说明图:
类加载
双亲委托机制(通过重写loadClass方法可以改变)
1. 寻找已加载的类(findLoadedClass方法)
2. 若没有找到,委托parent去找
3. 调用自己的findClass方法
4. 要是还没有则抛出异常
数据类型
基本数据类型
byte 一个字节数值,8bit,-128~127
short 两个字节数值
int 四个字节数值,整数默认类型,23亿,如果数据的大小没有超过byte/short/char的表述范围,则可以自动转型。
long 八个字节数值
float 1.000111f 不加字母默认是double
double 浮点数值可以用 314e-2 科学计数法的写法
boolean true和false
char 两个字节,数值对应Unicode字符
运算符
java 中有三种移位运算符
<< 左移运算符,num << 1, 相当于 num 乘以 2
>> 右移运算符,num >> 1, 相当于 num 除以 2
>>> 无符号右移,忽略符号位01(二进制的最高位是符号位,0 表示正,1 表示负),空位都以 0 补齐
位运算符 &|~^
C语言系的三目运算符
(布尔表达式)?A:B
高级数据类型
基本数据类型拥有对应的包装类Wrapper type,包装以后即可作为对象使用
boolean Boolean tostring以后为“true”或“false”
char Character
void Void
数值类型Number类子类:
byte Byte
short Short
int Integer Integer a = new Integer(1000);
(代码中-128到127之内数值默认用int缓存,不用Integer对象,例如Integer a=10;Integer b=10; a==b成立(实际只是int数据比较而不是对象比较))
long Long
float Float
double Double
字符串与数值互相转换
String intStr = "123";
//把一个特定字符串转换成int变量
int it1 = Integer.parseInt(intStr);
int it2 = new Integer(intStr);
String floatStr = "4.56";
//把一个特定字符串转换成float变量
float ft1 = Float.parseFloat(floatStr);
float ft2 = new Float(floatStr);
//把一个float变量转换成String变量
String ftStr = String.valueOf(2.345f);
//把一个double变量转换成String变量
String dbStr = String.valueOf(3.344);
//把一个boolean变量转换成String变量
String boolStr1 = String.valueOf(true);
String boolStr2 = true+"";
//把一个字符串转换成Boolean对象
Boolean bool= new Boolean("false");
字符串
String,StringBuilder,StringBuffer
检测字符串是否相等 检测两个字符串内容是否相等时使用“equals”
比较两个字符串的引用是否相等时用“=="
得到字符串的长度 字符串变量名.length();
从常量池获取字符串.intern()先从常量池中查找是否存在该常量值, 如果不存在则在池中创建, 如果已经存在则直接返回
字符串替换(不改变原字符串返回新字符串),replace(char oldChar, char newChar)参数不是正则,replaceFirst(String regex, String replacement),replaceAll(String regex, String replacement),移除前导空白和尾部空白trim()
字符串查找indexOf(String str)位置,判断startsWith,endsWith,否匹配给定的正则matches(String regex)
分割split(支持正则),截取String substring(int beginIndex, int endIndex)
拼接+或者string1.concat(string2)或者String.join
字符串格式化 String.format("%d",1),%d %f %s等
StringBuilder sb = new StringBuilder();
//追加字符串
sb.append("java");//sb = "java"
//插入
sb.insert(0 , "hello "); //sb="hello java"
//替换
sb.replace(5, 6, ","); //sb="hello, java"
//删除
sb.delete(5, 6);//sb="hellojava"
//反转
sb.reverse();//sb="avajolleh"
//改变StringBuilder的长度,将只保留前面部分
sb.setLength(5); //sb="avajo"
数组
int[] a = new int[3];//new int[]{5, 6, 8, 20};
int[] c = {23,43,56,78}; //长度:4,索引范围:[0,3]
int[][] a = new int[3][];a[0] = new int[n];(任意大小)
数组工具类Arrays
//定义一个a数组
int[] a = new int[]{3, 4 , 5, 6};
//定义一个a2数组
int[] a2 = new int[]{3, 4 , 5, 6};
//a数组和a2数组的长度相等,每个元素依次相等,将输出true
Arrays.equals(a , a2);
//通过复制a数组,生成一个新的b数组
int[] b = Arrays.copyOf(a, 6); //通过System.arraycopy实现
Arrays.toString(b);
//将b数组的第3个元素(包括)到第5个元素(不包括)赋为1
Arrays.fill(b , 2, 4 , 1);
//对b数组进行排序,升序
Arrays.sort(b);
//有序数组二分查找,如果查找值包含在数组中,则返回搜索键的索引;否则返回-1。
Arrays.binarySearch(Object[] a, Object key)
容器
ArrayList:数组 查看多于修改
add(元素) add(索引,元素) addAll(List) remove(元素) remove(索引) removeAll set(索引,元素) get(索引)
indexOf lastIndexOf clear contains containsAll subList 截取
for+get foreach() Iterator ListIterator
LinkedList :链表,修改多于查看 ,多了些链头与链尾的方法
HashSet: 重写 hashcode +equals
add(元素) remove(元素)
HashMap: 键不能重复 必须重写 hashcode +equals ,值可以重复
put(k,v) putAll remove(k) get(K) clear containsKey containsValue
获取值:values() keySet()+get entrySet()+getValue()
获取键:keySet entrySet() +getKey()
获取键与值: keySet()+get entrySet() +getKey() getValue()
LinkedHashMap 通过双向链表实现,保持了key-value放入时的顺序
Hashtable:键与值都不能为null 线程安全 Properties是Hastable的子类
Properties props = new Properties();
props.load(new FileInputStream(paramFile));
String driver = props.getProperty("driver");
WeakHashMap,将一对key, value放入到 WeakHashMap 里并不能避免该key值被 GC 回收,除非在 WeakHashMap 之外还有对该key的强引用
互相转换
Set set = new HashSet(new ArrayList());
List list = new ArrayList(new HashSet());
List arr = Arrays.asList("1", "2", "3");
//或者
String[] arr = {"1", "2"};
List list = new ArrayList(Arrays.asList(arr));
int[] arr = { 1, 2, 3 };
Set set = new HashSet(Arrays.asList(arr));
List list = new ArrayList(map.values());
Set set = new HashSet(map.values())
List list = new ArrayList(Arrays.asList("a","b"));
String[] arr = (String[])list.toArray(new String[list.size()]);
容器工具类Collections
List相关
Collections.reverse
Collections.shuffle
Collections.sort
Collections.swap Collections.rotate
Collections.binarySearch(list,vale) List需要是有序的
Collections.replaceAll
创建多线程可用同步集合
Collection c = Collections.synchronizedCollection(new ArrayList());
List list = Collections.synchronizedList(new ArrayList());
Set s = Collections.synchronizedSet(new HashSet());
Map m = Collections.synchronizedMap(new HashMap());
创建不可变集合
//创建一个空的、不可改变的List对象
List unmodifiableList = Collections.emptyList();
//创建一个只有一个元素,且不可改变的Set对象
Set unmodifiableSet = Collections.singleton("疯狂Java讲义");
//创建一个普通Map对象
Map scores = new HashMap();
scores.put("语文" , 80);
scores.put("Java" , 82);
//返回普通Map对象对应的不可变版本
Map unmodifiableMap = Collections.unmodifiableMap(scores);
迭代器Iterator
1)、java.util.Iterator + hasNext() next() remove()循环删除时使用,从集合中删除上一次next方法返回的元素
2)、foreach :java.lang.Iterable +iterator()
比较器
1)、实体类可以排序 实现实体类的java.lang.Comparable接口 的compareTo方法
2)、排序比较器(解耦、多种排序规则) 根据实体类实现一个java.util.Comparator类 实现compare方法然后
List+Collections.sort(list,myComparator)
TreeSet
TreeMap
面向对象
封装
通过private、protected、default 、public关键字实现属性或方法的封装
“高内聚,低耦合”
继承
extends 继承,扩展
Java中类只有单继承,没有像C++那样的多继承
方法重写(加@override注解)
=:方法名保持一致
>=: 子类权限修饰符可以大于等于父类的。
<=, <=: 子类的返回值类型小于等于父类的类型。 子类声明异常类型不能超过父类的类型。
Object类:
1. 是所有类的根基类
2. toString
3. equals、hashcode
4. wait、notify、notifyAll
构造方法是被隐式声明为 static 方法
构造方法函数:
1. 方法名必须跟类名保持一致
2. 无返回类型
3. 通过new来调用
4. 无参构造器问题:
a) 如果我们没有手动定义构造器,系统会自动为我们添加一个无参的构造器
b) 如果我们自己定义了构造器,系统就不会为我们添加无参构造器
5. 构造方法的第一句总是:super,即调用直接父类的构造方法。
a) 有继承关系的构造方法调用的顺序
super 指的是对直接父类的引用,super关键字必须是构造方法中的第一行语句。
可以通过super来访问父类中 被子类覆盖的方法或属性。
不能访问父类的父类的被覆盖的方法
this:
普通方法中,调用本方法的对象,方法中默认隐式参数。
构造方法中,正要初始化的对象。
还可以用来,调用其他的构造方法,this(参数。。);
static:
用它修饰的变量和方法,就变成了静态变量和静态方法。从属于类。通过类名即可调用。实际存储于方法区中。
静态初始化块static{ }
多态(polymorphism),父类可以使用子类的方法
三个必要条件:继承、方法的重写、父类引用指向子类对象
方法的重载(Overload):
两同(同一个类、同一个方法名)三不同(参数列表不同:类型、个数、顺序)
抽象类:
抽象类无法实例化,也就是说,不能 new 出来一个抽象类的对象(实例)
如果一个类中包含了抽象方法,那么这个类一定要声明成 abstract class,也
就是说,该类一定是抽象类;反之,如果某个类是抽象类,那么该类既可以
包含抽象方法,也可以包含具体方法。在子类继承父类(父类是个抽象类)的情况下,那么该子类必须要实现父类
中所定义的所有抽象方法;否则,该子类需要声明成一个 abstract class。
接口interface:
类实现接口 implements 可以多个接口名(接口可以多继承)
常量和抽象方法
常量默认是public static final 不可变
方法默认似public
可以多继承extends 多个接口
异常处理
Java 异常类类层次图:
Java 异常处理通过 5 个关键字 try、catch、throw、throws、finally 进行管理。
throw 用来抛出一个异常,在方法体内。语法格式为:throw 异常对象。
throws 用来声明方法可能会抛出什么异常,在方法名后,语法格式为:throws 异常类型 1,异常类型 2... 异常类型 n。
两种处理异常Exception的方式(Error也可以被catach处理,可以ctach Throwable及其子类,但是没有意义)
一、在方法中用 try...catch 语句捕获并处理异常,catach 语句可以有多个,用来匹配多个异常。例如:
public void p(int x){
try{...}
catch(Exception e)//可以多个,用|隔开
{...}finally{...}}
二、对于处理不了的异常或者要转型的异常,在方法的声明处通过 throws 语句抛出异常。例如:
public void test1() throws MyException{
...
if(....){throw new MyException();}
}
泛型
参数化类型,限制参数类型
声明泛型变量<T>
泛型不能从父类继承
泛型类(类名后有<T>)、泛型接口、泛型方法(方法名前有<T>)、泛型擦除(实际运行的代码会被擦除)、泛型嵌套
容器中的泛型的抽象描述,通配符? 不管你限定了什么泛型T,代表所有类型(? extends Object),也可以具体限定<? super T> <? extends T>
受限泛型,extends super
//例子 <? extends T>返回都可以为T类型,但是不能添加数据,<? super T> 只能能加T类型(以及父类)的dest List,但返回值类型不确定
public class Collections {
public static <T> void copy(<? super T> dest, List<? extends T> src)
{
for (int i=0; i<src.size(); i++)
dest.set(i,src.get(i));
}
}
反射Reflect
原理,每个类都有Class类存储着类的信息
还可以获取注解和泛型信息!!
反射操作
1、通过反射得到 Class 类
①类名.class
②对象.getClass()
③使用 Class.forName(“类 path”)
Class<?> clazz = Class.forName(path);
2、通过反射操作 Constructor
//操作无参构造
Classclazz = Class.forName("类path");
Person p = (Person)clazz.newInstance();//生成对象
p.setName("Joash");
//操作有参构造
Classclazz = Class.forName("类path");
//clazz.getConstructors();//获取自身及父类public构造方法,自身全部构造方法用getDeclaredConstructors
Constructor cs =clazz.getConstructor(String.class,String.class);//获取两个String参数的构造
Person p = (Person)cs.newInstance("Joash","100");
3、通过反射操作 Field
Classclazz = Class.forName("类path");
Person p = (Person)clazz.newInstance();
//clazz.getFields(); //获取所有自身的public方法和父类Object的public属性
Filed f =clazz.getField("fieldName");//自身全部属性用getDeclaredField
f.getAccessible(true);//设置私有属性可操作
f.set(p,"Joash");
4、通过反射操作Method
Classclazz = Class.forName("类path");
Person p = (Person)clazz.newInstance();
//clazz.getdMethods(); //获取所有自身的public方法和父类Object的public方法
Method m =clazz.getDeclaredMethod("setName",String.class);//获取自身的public、protected、private的方法
//m.getAccessible(true);//设置可操作私有属性
m.invoke(p,"Joash");//让setName方法执行
//PS:如果操作静态方法,无需类的实例,即m.invoke(null,"Joash");
//多参数
Method method = obj.getdMethod("methodName", new Class[]{String.class,int.class});
method.invoke(target,new Object[]{"str",123});
案例使用:泛型擦除
ArrayList<Integer> arr = new ArrayList<Integer>();
Class c = arr.getClass();
Method m = c.getMethod("add",Object.class);
m.invoke(arr,"add_string");
动态代理
/**
* 1、写一个类实现InvocationHandler接口
* @author Administrator
*
*/
public class LogProxy implements InvocationHandler {
private LogProxy(){}
//2、创建一个代理对象
private Object target;
//3、创建一个方法来生成对象,这个方法的参数是要代理的对象,getInstacne所返回的对象就是代理对象
public static Object getInstance(Object o) {
//3.1、创建LogProxy对象
LogProxy proxy = new LogProxy();
//3.2、设置这个代理对象
proxy.target = o;
//3.3、通过Proxy的方法创建代理对象,第一个参数是要代理对象的classLoader
//第二个参数是要代理对象实现的所有接口,第三个参数是实现类InvocationHandler的对象
//此时的result就是一个代理对象,代理的是o
Object result = Proxy.newProxyInstance(o.getClass().getClassLoader(),
o.getClass().getInterfaces(), proxy);
return result;
}
/**
* 当有了代理对象之后,不管这个代理对象执行什么方法,都会调用以下的invoke方法
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// if(method.getName().equals("add")||method.getName().equals("delete")) {
// Logger.info("进行了相应的操作");
// }
Object obj = method.invoke(target, args);
if(method.isAnnotationPresent(LogInfo.class)) {
LogInfo li = method.getAnnotation(LogInfo.class);
Logger.info(li.value());
}
return obj;
}
}
注解
注解Annotation,可以用代码获取的解释说明
定义注解
@Target(value = { ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface SxtField {
String columnName();
String type();
int length();
}
使用注解
@SxtField(columnName = "id", type = "int", length = 10)
private int id;
反射获取注解(另有APT获取注解(Java8后插入式注解处理API(Pluggable Annotation Processing API)代替),Android中常用)
Class<?> clazz = Class.forName("Annotation_$Student");
// 获得类的所有有效注解
Annotation[] annotations = (Annotation[]) clazz.getAnnotations();
for (Annotation a : annotations) {
System.out.println(a);
}
// 获得类的指定的注解
SxtTable st = (SxtTable) clazz.getAnnotation(SxtTable.class);
System.out.println(st.value());
// 获得类的属性的注解
Field f = clazz.getDeclaredField("studentName");
SxtField sxtField = f.getAnnotation(SxtField.class);
System.out.println(sxtField.columnName() + "--" + sxtField.type()+ "--" + sxtField.length())
数据流IO
字节流,使用的数组是字符数组char [] chs
输入流:InputStream read()+close()
FileInputStream()
输出流:OutputStream write() +flush() +close()
FileOutputStream
字符流,使用的数组是字节数组byte [] bt
输入流:Reader read() +close()
FileReader()
输出流:Writer write() +flush() +close()
FileWriter()
缓冲流
1)、字节缓冲流
BufferedInputStream
BufferedOutputStream
2)、字符缓冲流
BufferedReader readLine()
BufferedWriter newLine()
转换流:
编码与解码概念
编码:字符 --编码字符集->二进制
解码: 二进制 --解码字符集->字符
InputStreamReader(字节输入流,"解码集")
OutputStreamWriter(字符输出流,"编码集")
节点流
1、字节数组 字节 节点流
输入流:ByteArrayInputStream read() + close()
输出流:ByteArrayOutputStream write() +toByteArray()
其他处理流
1、基本类型+String 保留数据+类型
输入流:DataInputStream readXxx
输出流:DataOutputStream writeXxx
2、引用类型 (对象) 保留数据+类型 对象需要 implements Serializable
反序列化 输入流:ObjectInputStream readObject()
序列化 输出流:ObjectOutputStream writeObject()
注意:
1)、先序列化后反序列化;反序列化顺序必须与序列化一致
2)、不是所有的对象都可以序列化, java.io.Serializable,不是所有的属性都需要序列化,transient
3、打印流 PrintStream println() print()
4、三个常量 : System.in /out/err System.setIn() setOut() setErr()
装饰中模式使用数据流
BufferedReader fr = new BufferedReader(
new InputStreamReader(new FileInputStream(
"E:\\Desktop\\test.c"), "gbk"));
File类
File
// 以当前路径来创建一个File对象
File file = new File(".");
1、文件名
getName() 文件名、路径名
getPath()路径名
getAbsoluteFile() 绝对路径所对应的File对象
getAbsolutePath() 绝对路径名
getParent() 父目录 ,相对路径的父目录,可能为null 如. 删除本身后的结果
lastModified()修改时间
2、判断信息
exists()
canWrite()
canRead()
isFile()
isDirectory()
isAbsolute():消除平台差异,ie以盘符开头,其他以/开头
3、长度 字节数 不能读取文件夹的长度
length()
4、创建、删除
createNewFile() 不存在创建新文件,存在返回false
delete() 删除文件
static createTempFile(前缀3个字节长,后缀默认.temp) 默认临时空间
static createTempFile(前缀3个字节长,后缀默认.temp,目录)
deleteOnExit() 退出虚拟机删除,常用于删除临时文件
5、操作目录
mkdir() 创建目录,必须确保 父目录存在,如果不存在,创建失败
mkdirs() 创建目录,如果父目录链不存在一同创建
list() 文件|目录 名字符串形式
listFiles()
static File.listRoots() 静态方法列出所有的磁盘根路径。
//以读、写方式打开一个RandomAccessFile对象
RandomAccessFile raf = new RandomAccessFile("out.txt" , "rw")
//将记录指针移动到out.txt文件的最后
raf.seek(raf.length());
raf.write("追加的内容!\r\n".getBytes());
NOI
Path类
Files
Paths工具类
线程Threads
实现Runnable +run(),复杂的方法Callable Futuer
启动:使用静态代理
1、创建真实角色
2、创建代理角色 Thread+引用
3、代理角色.start()
Thread newThread = new Thread(new newRunnable());
newThread.start();
try {
newThread.join();
//线程结束做点什么
} catch (Exception e) {
e.printStackTrace();
}
class newRunnable implements Runnable {//实现Runnable接口
@Override
public void run() {
//新线程做点什么
}
}
Thread.currentThread().getName()
Thread.sleep(1000);// 调用sleep方法让当前线程暂停1s。
Thread.yield();//使用yield方法让当前线程让步
ThreadLocal.set(object)线程自己的数据(只有一个),通过ThreadLocal.get()获取,实际通过用threadID做keyMap中实现
同步:并发 多个线程访问同一份资源 确保资源安全 -->线程安全
DaemonThread守护线程 isDaemon
DaemonThread t = new DaemonThread();
// 将此线程设置成后台线程
t.setDaemon(true);
// 启动后台线程
t.start();
线程优先级 Thread.currentThread().setPriority(6); 1-10
// 设置该线程为最高优先级
high.setPriority(Thread.MAX_PRIORITY);
// 设置该线程为最低优先级
low.setPriority(Thread.MIN_PRIORITY);
线程通信
线程池
newFixedThreadPool:newFixedThreadPool,创建固定大小的线程池,poolCoreSize和maxPoolSize 相等,到达coreSize,则将新的任务放到缓存队列,有线程执行完毕,直接去取。
newSingleThreadExecutor:newSingleThreadExecutor,创建一个单线程的线程池,核心池的大小和最大池大小都为1
newCacheThreadPool:newCacheThreadPool,无大小限制的线程池,提交一个任务就创建一个线程执行
// 创建一个具有固定线程数(6)的线程池
ExecutorService pool = Executors.newFixedThreadPool(6);
// 向线程池中提交两个线程
pool.submit(new MyThread());
pool.submit(new MyThread());
// 关闭线程池
pool.shutdown();
synchronized -->同步
一、同步块synchronized(引用类型|this|类.class){}
二、同步方法synchronized (synchronized 关键字是不能继承的)
实用工具库:
正则表达式
String line = "sting....";
// 编译正则表达式
Pattern p = Pattern.compile("[\\w[.-]]+@[\\w[.-]]+\\.[\\w]+");
// 忽略大小写的写法
// Pattern p = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(line);
m.matches()//判断是否匹配
m.replaceAll("哈哈:)");//替换
while(m.find()) {// 查找字符串中是否有匹配正则表达式的字符/字符串
//group()可加参数1,2,3获取正则()获取值
System.out.println(m.group() + "子串的起始位置:"+ m.start() + ",其结束位置:" + m.end());
}
//字符串中的正则
str.replaceFirst("re\\w*" , "哈哈:)")
时间相关类
sqlDate和sqlTime是不完整的,sqlTimeStamp和uitlDAte是完整的。
日期参数获取
Calendar cal = Calendar.getInstance();
int day = cal.get(Calendar.DATE);
int month = cal.get(Calendar.MONTH) + 1;
int year = cal.get(Calendar.YEAR);
int dow = cal.get(Calendar.DAY_OF_WEEK);
int dom = cal.get(Calendar.DAY_OF_MONTH);
int doy = cal.get(Calendar.DAY_OF_YEAR);
获取今日0时
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.MILLISECOND, 0);
Date today = new Date(cal.getTimeInMillis());//昨天-1000*60*60*24
获取此刻日期字符串
/**
SimpleDateFormat函数语法:
G 年代标志符 公元
y 年
M 月
d 日
h 时 在上午或下午 (1~12)
H 时 在一天中 (0~23)
m 分
s 秒
S 毫秒
E 星期
D 一年中的第几天
F 一月中第几个星期几
w 一年中第几个星期
W 一月中第几个星期
a 上午 / 下午 标记符
k 时 在一天中 (1~24)
K 时 在上午或下午 (0~11)
z 时区
*/
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
long time = System.currentTimeMillis();
System.out.println(sdf.format(time));
sdf.parse(sdf.format(time));
JDBC
基础
Class.forName("com.mysql.jdbc.Driver");// 1.加载驱动,使用反射的知识,现在记住这么写。
// 2.使用DriverManager获取数据库连接,
// 其中返回的Connection就代表了Java程序和数据库的连接
// 不同数据库的URL写法需要查驱动文档知道,用户名、密码由DBA分配
//getConnection(url, user , pass);
conn = DriverManager.getConnection("jdbc:mysql://localhost/mydata?user=root&password=root");
stmt = conn.createStatement();// 3.使用Connection来创建一个Statment对象
// 4.执行SQL语句
/*
Statement有三种执行sql语句的方法:
1 execute 可执行任何SQL语句。- 返回一个boolean值,如果执行后第一个结果是ResultSet,则返回true,否则返回false
2 executeQuery 执行Select语句 - 返回查询到的结果集
3 executeUpdate 用于执行DML语句。- 返回一个整数,代表被SQL语句影响的记录条数
*/
rs = stmt.executeQuery("select * from dept");
// ResultSet有系列的getXxx(列索引 | 列名),用于获取记录指针
// 指向行、特定列的值,不断地使用next()将记录指针下移一行,
// 如果移动之后记录指针依然指向有效行,则next()方法返回true。
while (rs.next()) {
System.out.println(rs.getString("deptno"));
}
// 获取的DatabaseMetaData对象
DatabaseMetaData dbmd = conn.getMetaData();
// 获取当前数据库的全部数据表
rs = dbmd.getTables(null,null, "%" , new String[]{"TABLE"});
// 获取student_table表的主键
rs = dbmd.getPrimaryKeys(null , null, "student_table");
// 获取当前数据库的全部存储过程
rs = dbmd.getProcedures(null , null, "%");
// 获取teacher_table表和student_table之间的外键约束
rs = dbmd.getCrossReference(null,null, "teacher_table", null, null, "student_table");
// 获取student_table表的全部数据列
rs = dbmd.getColumns(null, null, "student_table", "%");
防止SQL注入
pstmt = conn.prepareStatement("insert into dept2 values (?, ?, ?)");
pstmt.setInt(1, deptno);
pstmt.setString(2, dname);
pstmt.setString(3, loc);
pstmt.executeUpdate();
批量执行
PreparedStatement ps = conn.prepareStatement("insert into dept2 values (?, ?, ?)");
ps.setInt(1, 61);
ps.setString(2, "haha");
ps.setString(3, "bj");
ps.addBatch();
ps.setInt(1, 62);
ps.setString(2, "haha");
ps.setString(3, "bj");
ps.addBatch();
ps.executeBatch();
回滚支持
conn.setAutoCommit(false);
stmt = conn.createStatement();
stmt.addBatch("insert into dept2 values (51, '500', 'haha')");
stmt.addBatch("insert into dept2 values (52, '500', 'haha')");
stmt.executeBatch();
conn.commit();
conn.setAutoCommit(true);
} catch(SQLException e) {
try {
if(conn != null)
{
conn.rollback();
conn.setAutoCommit(true);
}
}
}
网络Net
1、InetAddress封装 IP 及DNS方法:
getHostAddress() 返回ip地址
getHostName() 返回域名|本机为计算机名
InetAddress.getLocalHost();
InetAddress.getByName("ip地址|域名");
InetSocketAddress:封装端口
1)、创建对象:
InetSocketAddress(String hostname, int port)
InetSocketAddress(InetAddress addr, int port)
2)、方法:
getAddress()
getHostName()
getPort()
2、URL
URI(Uniform resource identifier)统一资源标识符,用来唯一的标识一个资源。
URL(Uniform Resource Locator)统一资源定位器,它是一种具体的URI
String keyWord = URLDecoder.decode("%B7%E8%BF%F1java", "GBK");
String urlStr = URLEncoder.encode("疯狂Android讲义" , "GBK");
四部分组成: 协议 存放资源的主机域名 端口 资源文件名(/)
创建
URL(String spec) :绝对路径构建
URL(URL context, String spec) :相对路径构建
方法
System.out.println("协议:"+url.getProtocol());
System.out.println("域名:"+url.getHost());
System.out.println("端口:"+url.getPort());
System.out.println("资源:"+url.getFile());
System.out.println("相对路径:"+url.getPath());
System.out.println("锚点:"+url.getRef()); //锚点
System.out.println("参数:"+url.getQuery());//?参数 :存在锚点 返回null ,不存在,返回正确
3、TCP: ServerSocket Socket
基于tcp: 面向连接 安全 可靠 效率低 ,类似于打电话
一、面向连接: 请求-相应 Request --Response
二、Socket编程
1、服务器: ServerSocket
2、客户端: Socket
5、代理
// 创建一个代理服务器对象
Proxy proxy = new Proxy(Proxy.Type.HTTP , new InetSocketAddress("129.82.12.188", PROXY_PORT));
// 使用指定的代理服务器打开连接
URLConnection conn = url.openConnection(proxy);
4、UDP: DatagramSocket DatagramPacket
UDP:以数据为中心 非面向连接 不安全 数据可能丢失 效率高
客户端:
1)、创建客户端 DatagramSocket 类 +指定端口
2)、准备数据 字节数组
3)、打包 DatagramPacket +服务器地址 及端口
4)、发送
5)、释放资源
服务器端:
1)、创建 服务端 DatagramSocket 类 +指定端口
2)、准备接受容器 字节数组 封装 DatagramPacket
3)、包 接受数据
4)、分析
5)、释放资源
其他
//获取Java程序关联的运行时对象
Runtime rt = Runtime.getRuntime();
//运行记事本程序
rt.exec("notepad.exe");
//处理器数量
rt.availableProcessors();
//空闲内存数
rt.freeMemory();
//总内存数
rt.totalMemory();
//可用最大内存数
rt.maxMemory();
//运行记事本程序
Runtime rt = Runtime.getRuntime();
rt.exec("notepad.exe");
//获取系统所有的环境变量
Map<String,String> env = System.getenv();
for (String name : env.keySet())
{System.out.println(name + " ---> " + env.get(name));}
//获取指定环境变量的值
System.out.println(System.getenv("JAVA_HOME"));
//获取所有的系统属性
Properties props = System.getProperties();
//将所有系统属性保存到props.txt文件中
props.store(new FileOutputStream("props.txt") , "System Properties");
//输出特定的系统属性
System.out.println(System.getProperty("os.name"));
大数运算
BigDecimal
BigDecimal f1 = new BigDecimal("0.05");
BigDecimal f2 = BigDecimal.valueOf(0.01);
BigDecimal f3 = new BigDecimal(0.05);
f1.add(f2).doubleValue();
f1.subtract(f2).doubleValue();
f1.multiply(f2).doubleValue();
f1.divide(f2 , DEF_DIV_SCALE , BigDecimal.ROUND_HALF_UP).doubleValue();//需要设置精度
随机值Random,ThreadLocalRandom
Random rand = new Random();
rand.nextBoolean();
byte[] buffer = new byte[16];
rand.nextBytes(buffer);
//生成0.0~1.0之间的伪随机double数
rand.nextDouble();
//生成0.0~1.0之间的伪随机float数
rand.nextFloat();
//生成平均值是 0.0,标准差是 1.0的伪高斯数
rand.nextGaussian();
//生成一个处于int整数取值范围的伪随机整数
and.nextInt();
//生成0~26之间的伪随机整数
rand.nextInt(26);
//生成一个处于long整数取值范围的伪随机整数
rand.nextLong();
Objects
ObjectsTest obj;
Objects.equals(obj,obj1);
Objects.hashCode(obj);
Objects.toString(obj);
Objects.requireNonNull(obj, "obj参数不能是null!");
Math
//取整,返回小于目标数的最大整数。
Math.floor(-1.2 );
//取整,返回大于目标数的最小整数。
Math.ceil(1.2);
//四舍五入取整
Math.round(2.3);
//计算平方根。
Math.sqrt(2.3);
//计算立方根。
Math.cbrt(9);
//返回欧拉数e的n次幂。
Math.exp(2);
//计算乘方
Math.pow(3, 2);
//计算绝对值。
Math.abs(-4.5);
//找出最大值
Math.max(2.3 , 4.5);
//计算最小值
Math.min(1.2 , 3.4);
//返回一个伪随机数,该值大于等于 0.0 且小于 1.0。
Math.random();