String str="IronMan.jpg"; str.indexOf("n");//该字符第一次出现的位置 String subStr=str.substring(0,4);//截取字符串(含头不含尾) char chr=str.charAt(3);//获取该字符所在的位置 boolean flag1=str.endsWith(".jpg");//true;判断以什么结尾 boolean flag2=str.startsWith("Iam");//false;判断以什么开头 String lower = str.toLowerCase();//IRONMAN.JPG;字符串英文部分全部大写 String upper = str.toUpperCase();//ironman.jpg;字符串英文部分全部小写 String str2="\n IronMan \t "; String trim=str2.trim();//去除两端多余空白 double pi=3.14; String strPi=String.valueOf(pi);//valueOf可以将基本类型(int,long,bool等等)转为字符串形式
2.StringBuilder: 封装可变字符串,用于修改字符串,减少内存开销
/**StringBuffer是线程安全的,同步处理的,性能稍慢;StringBuilder是非线程安全的,并发处理的,性能稍快*/
append(String str) //追加字符串; insert(int dstOffset, String str) //插入字符串(dstOffset开始插入位置(下标+1),str被插入的字符串)(str的首字母的位置是dstOffset) delete(int start,int end) //删除字符串(含头不含尾)(如果删除末尾一段则是(start,length+1)); replace(int start, int end, String str) //替换字符串 reverse() //字符串反转 StringBuilder str= new StringBuilder("Iron"); str.append("Man").append("jpg").insert(6,".");
3.正则表达式:
①基本规则:
. 表示任意一个字符; \d 表示任意一个数字
\w 表示任意一个单词字符 \s 表示任意一个空白字符
\D 表示任意一个非数字字符 \W 表示任意一个非单词字符
\S 表示任意一个非空白字符
[] 表示字符集合; 例如: [123abc] 表示字符只能是这六个; [a-z0-9] 表示字符是小写字符或者0~9的数字
+ 表示内容可以连续出现至少一次以上 * 表示内容出现0到若干次
? 表示内容出现0-1次 {n} 表示内容必须出现n次
{n,m} 表示内容至少出现n-m次 {n,} 表示内容出现至少n次
在正则表达式的开始添加"^"以及末尾添加"$"来表示一个整体;
②String正则相关API: ①matches() 表示字符串是否符合正则表达式,返回true或false;
②String[] split(Sting regex) 将字符串按照规则拆分,返回一个数组
③String replaceAll(String regex,String replacement) 传入的参数是正则式和被替换的字符串,返回被替换后的字符串
String emailRegex= "^[a-zA-Z0-9_.-]+@([a-zA-Z0-9-]+\\.)+[a-zA-Z0-9]{2,4}$";
String email="[email protected]"
boolean flag=email.matches(emailRegex);//
4.Object是所有类的顶级父类
所以所有类都要重写ToString()和equals()
/**鼠标放到类名上,(Alt+Shift+S)右键→Source→Generate toSting()或Generate hashCode() and equals()*/
重写equals模板:
public boolean equals(Object obj){ if(obj==null) return false; if(this==obj) return true; if(obj instanceof xxx){ xxx other=(xxx)obj; return xx; } return false; }
5.包装类
①基本类型转化为包装类
Integer i = Integer.valueOf(1); Double d = Double.valueOf(1.1);
②自动装箱和自动拆箱:
int i = new Integer(1);//自动拆箱:包装类转为基本类型 Integer a=1;//自动装箱:基本类型转为包装类
6.日期Date
①
Date date = new Date();//date为本地时间 long time=date.getTime();//1970年1月1日至今的毫秒数
②SimpleDateFormat 日期时间格式
Date now=new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String nowSdf=sdf.format(now);
③String格式转化为Date
Date parse(String str)
7.Calendar
①设置日期及时间分量:
/**设置年月日*/ Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.YEAR,2017); //年 calendar.set(Calendar.Month,4); //月(数字0~11表示1~12月) calendar.set(Calendar.Month,Calendar.MAY); //月(用大写英文单词) calendar.set(Calendar.DAY_OF_MONTH,21); //日 /**获取年月日常量[注意月份需要+1]*/ int year = calendar.get(Calendar.YEAR);//获取:年 int month = calendar.get(Calendar.Month);//获取:月 (这里获得的数值是0~11,与之对应的是1~12月) /**获得某月最大天数*/ int maxThisMonth=calendar.getActualMaximum(Calendar.DAY_OF_MONTH);//获得当前本地时间那个月的最大天数 /**时间分量计算*/ calendar.add(Calendar.DAY_OF_YEAR,1);//表示明天;(如果今天2017-01-31,那么明天的值为2017-02-01) Calendar的void setTime(Date date),允许我们为Calendar设置Date对象所表示的时间。 Calendar的 Date getTime(),允许我们获取一个使用Date对象描述的Calendar所表示的时间。 Calendar calendar = Calendar.getInstance(); Date date = calendar.getTime();
8.集合Collection
①Collection派生出了两个子接口,一个是List另一个则是Set。
List:可重复集 Set:不可重复集
Collection<String> c1= new ArrayList<String>();//泛型:Integer;Double;Character;String;Long;Element(需要import) c1.add("a"); c1.add("IronMan"); Collection<Point> c2 = new ArrayList<Point>(); c2.add(new Point(1,2)); c2.add(new Point(2,3); boolean flag=list2.contains(new Point(1,1));//判断某元素是否存在 /**int size();void clear();boolean isEmpty() */ Collection<Charater> c3= new HashSet<Charater>(); boolean flag1=c3.isEmpty();//是否为空 c3.add('a'); c3.add('b'); System.out.println(c3.size());//获取集合元素总数 c3.clear();//清空集合
②迭代器:
Collection<Integer> c = new HashSet<Integer>(); c.add(1); c.add(2); Iterator<Integer> ite=c.iterator(); while(ite.hasNext()){ Integer intNum=ite.next(); System.out.println(intNum); }
③增强for循环:本质就是迭代器,但只适用于集合或数组
for(元素类型 e:集合或数组){
循环体
}
9.List接口的两个常见的实现类为ArrayList(动态数组)和LinkedList(链表),
二者逻辑上一样,性能上有差别(ArrayList适合随机访问,LinkedList更适合插入和删除(对于两端的操作效率更高))
/**E get(int index):获取集合中指定下标对应的元素,下标从0开始。 *E set(int index, E elment):将给定的元素存入给定位置,并将原位置的元素返回 *void add(int index,E element):将给定的元素插入到指定位置,原位置及后续元素都顺序向后移动 *E remove(int index): 删除给定位置的元素,并将被删除的元素返回。 *List<E> subList(int fromIndex, int toIndex); subList获取的List与原List占有相同的存储空间,对子List的操作会影响的原List。 *<T>T[] toArray(T[] a) List转换为数组 *static <T>List<T> asList<T… a> 数组转换为List */ List<String> list = new ArrayList<String>(); list.add("java"); list.add("php"); list.add("c#"); for(int i=0;i<list.size();i++){ System.out.println(list.get(i)); } String[] strArr = list.toArray(new String[] {});//List转换为数组 //System.out.println(strArr);//这里没有重写头String直接输出是个奇怪的结果 System.out.println(Arrays.toString(strArr));
10.List排序
/** void sort(List<T> list) 自然排序(从小到大) *int compareTo(T t) 比较大小(返回值大于0表示当前对象比参数对象大) */ List<Integer> list= new ArrayList<Integer>(); Collections.sort(list);
11.队列:
Queue:一端添加(offer)元素,另一端取出(poll)元素;FIFO(先进先出)
Deque:双端队列,队列的两端分别可以入队(offer)和出队(poll)
Stack:栈,FILO(先进后出)
12.查询表
Map: 一组键值对(key-value),key不能重复
/** *V put(K k,V v) Map中添加一个key-value对 存入Map中;若当次存入的key已经在Map中存在,则是替换value操作,而返回值则为被替换的元素。若此key不存在,那么返回值为null。 *V get(Object key) 根据key去查找Map中对应的value并返回 *boolean containsKey(Object key) 检测Map中是否包含给定的key */
13.HashMap
14.File文件操作
File dir1= new File("D:/test");//绝对路径;创建一个对象代表文件夹 dir1.mkdir();//真实创建一个文件夹 File dir2= new File("test01/test02/test03");相对路径;创建一个对象代表一系列文件夹 dir2.mkdirs();//真实创建一系列父子文件夹 File file1=new File("hello.txt");//创建一个对象代表文件 file1.createNewFile();//真实创建文件 File file2=new File(dir1,"hello.txt");//可以添上路径 file2.createNewFile(); File(String pathname) File(File parent,String child) boolean isFile() //该方法若返回true,这表示File表示的是一个文件。 long length() //返回的long值表示该文件所占用的字节量。 boolean exists() //若该File表示的文件或目录存在则返回true,否则返回false。 boolean createNewFile() boolean delete() boolean isDirectory()
15.RandomAccessFile
①只读: RandomAccessFile(File file,String mode)
RandomAccessFile(String filename,String mode)
②读写:
RandomAccessFile raf = new RandomAccessFile(file,”rw”); void write(int d) // 根据当前指针所在位置处写入一个字节 int read() //当前指针位置读取一个byte(8位) 填充到int的低八位, 高24位为0, 返回值范围正数: 0~255, 如果返回-1表示读取到了文件末尾EOF(EOF:End Of //File)! 每次读取后自动移动文件指针, 准备下次读取。 void write(byte[] d) //根据当前指针所在位置处连续写出给定数组中的所有字节 void write(byte[] d,int offset,int len) // 根据当前指针所在位置处连续写出给定数组中的部分字节 int read(byte[] b) //从文件中尝试最多读取给定数组的总长度的字节量,返回值为实际读取到的字节量 void close() //对文件访问的操作全部结束后,一定要close long getFilePointer() //获取当前指针位置 void seek(long pos) // 移动指针位置
16.基本IO操作:
FileOutputStream fos = new FileOutputStream("test.txt"); byte[] data="HelloWorld".getBytes(); fos.write(data); //写入HelloWorld fos.write(data,5,5);// 再写入World
17.缓冲流,转换流:
一般写文本都要明确文本编码
FileOutputStream fos = new FileOutputStream("test_copy.txt");//"输出流"→"写出"(write) BufferedOutputStream bos=new BufferedOutputStream(fos); OutputStreamWriter osw = new OutputStreamWriter(bos,"utf-8"); PrintWriter out=new PrintWriter(osw,true);//最常用的写文件高级流 FileInputStream fis = new FileInputStream("test.txt");//"输入流"→"读入"(read) BufferedInputStream bis= new FileInputStream(fis); InputStreamReader isr = new InputStreamReader(bis,"utf-8"); BufferedReader in = new BufferedReader(isr);//最常用的读取文件高级流(方法readLine()返回文本中一行数据)
18.异常处理:
try{ //可能出现异常的代码片段 }catch(NullPointerException e){ //... }catch(Exception e){ e.printStackTrace(); }finally{//finally为统一出口 //... }
19.多线程
①匿名内部类创建线程:
Thread thread = new Thread(){ public void run(){ //xxx; } }; thread.start();
②常用方法:
long getId() //返回该线程的标识符 String getName() //返回该线程的名称 int getPriority() //返回线程的优先级 Thread.state getState() //获取线程的状态 boolean isAlive() //测试线程是否处于活动状态 boolean isDaemon() //测试线程是否为守护线程 boolean isInterrupted() //测试线程是否已经中断
③线程优先级:划分为10级,1~10;
Thread.MIN_PRIORITY 表示1;
Thread.NORM_PRIORITY表示5;
Thread.MAX_PRIORITY 表示10;
④守护线程: 当进程中只剩下守护线程时,所有守护线程强制终止;
守护线程和普通线程表现没什么区别,加上setDaemon(true)变为守护线程;
void setDaemon(boolean);
⑤yield方法使当前线程主动让出当次CPU时间片回到Runnable状态
static void yield()
20.线程同步:
①临界资源:
多线程共享实例变量;多线程共享静态公共变量;
②锁机制支持原子性:
同步代码块(synchronized)
③线程安全:StringBuffer; Vector;Hashtable;Collections.synchronizedList();
非线程安全:StringBuilder; ArrayList; LinkedList; HashSet; HashMap;
将给定非安全的List,Set转换为线程安全的:
List<String> list = new ArraayList<String>(); list = Collections.synchronizedList(list); Set<String> set = new HashSet<String>(list);//list复制到set中,重复的元素只保留一个 set=Collections.synchronizedSet(set);
④线程池作用: 控制线程数量;重用线程;
ExecutorService threadPool = Executors.newFixedThreadPool(2);//创建容量为2的线程池
21.套接字:Socket,用于描述IP地址和端口,是一个通信链的句柄.
Socket socket1 = new Socket("localhost",8088); //Socket socket2 = new Socket("176.6.13.253",8088); InetAddress addres1=socket1.getLocalAddress();//获取套接字绑定的本地地址 int localport=socket1.getLocalPort();//获取本地使用的端口号 String hostaddress = socket1.getHostAddress();//返回IP地址字符串 String canonicalhostname = socket1.getCanonicalHostName();//获取此IP地址的完全限定域名
C-S端通信模型: 待补充
22. XML(EXtensible Markup Language)可扩展标记语言
①XML表格式:
<?xml version="1.0" encoding="UTF-8"?> <list> <emp id="1"> <name>司马懿</name> <age>11</age> <gender>男</gender> <salary>3000</salary> </emp> <emp id="2"> <name>奥黛丽赫本</name> <age>22</age> <gender>女</gender> <salary>4000</salary> </emp> <emp id="3"> <name>钢铁侠</name> <age>33</age> <gender>男</gender> <salary>50000</salary> </emp> </list>
② 解析XML大致步骤:
1.创建SAXReader;
2.读取要解析的XML文档并生成Document对象;
这一步就是DOM解析耗时耗资源的地方了,因为需要将XML文档都读取完毕并载入内存
3.通过Document对象获取根元素;
4.按照XML文档的结构从根元素开始逐级获取子元素以达到遍历XML文档数据的目的;
③写出XML文档的大致步骤:
1.创建Document队形表示一个空白文档;
2.向Document中添加根元素;
3.按照XML设计的结构向根元素中逐级添加子元素及数据;
4.创建XMLWriter
5.使用XMLWriter将Document对象写出以生成XML文档
④解析并写出核心代码示例:
读取XML文件:
① SAXReader reader = new SAXReader();
② Document document= reader.read(new File("Hello.xml"));
③ Element root =document.getRootElement();//根节点
④ List<Element> list = root.elements();//list存放所有(root下的子元素
⑤创建一个集合用于保存从XML文档解析的信息:
list: List<Type> listName1= new ArrayList<Type>();
map: Map<keyType,valueType> mapName1= new HashMap<keytType,valueType>();
⑥把信息保存到特定集合中去
list: for(Element e:listName1){
//获取对应内容
Type a=e.elementText("xxx");
//int b=Integer.parseInt(e.elementText("xxx"));
//double c=Double.valueOf(e.elementText("xxx"));
}
map: for(Element e:mapName1){
//获取内容
Type key=e.getName();
Type value=e.getTextTrim();
mapName1.put(key,value);
}
23.XPath 按路径定位节点,对获取XML中部分数据操作有良好的效果(用的较少但很有效)
★易错点★
①集合和数组里存储的是对象的引用;
②方法中声明的局部变量在栈中分配;对象(含属性)在堆中分配
③常量和变量比较时建议把常量写在前面:
例: "钢铁侠".equals(str);//str.equals.("钢铁侠");避免可能为空的str带来的问题
④字符串的字面量,常量运算, 重用同一个字符串
String s1 = "123abc"; //123abc String s2 = 123+"abc"; //123abc String s3 = '1'+23+"abc"; //72abc String s4 = "1"+23+"abc"; //123abc
⑤建表: List<Element> hellolist= new ArrayList<Element>();//泛型:Integer;Double;Character;String;Long;Element(需要import)
for(Element e:hellolist){//增强for循环
System.out.print(e+" ");
}
for(int i=0;i<hellolist.size;i++){//for循环
System.out.print(hellolist.get(i)+" ");
}
Iterator<String> ite = list.iterator();//迭代器
while(ite.hasNext()){
String str=ite.next();
System.out.print(str+" ");
}
⑥字符型转为整型: Integer.parseInt(str);
⑦list转为数组:
String[] strArr = list.toArray(new String[] {});
//System.out.println(strArr);//这是奇怪的结果,可能是没重写toString
System.out.println(Arrays.toString(strArr));