Java CookBook(一)
Java字符串和正则表达式
String是固定不变的,即当你改变String时实际是上创建了一个新字符串,而原来的字符串保持不变。StringBuffer和StringBuilder允许内容是可变的,它们都提供setCharAt(),insert()等修改字符串内容的方法。StringBuffer是线程安全的,在多线程应用中必须使用StringBuffer。StringBuilder不是线程安全的,当不使用多线程时,使用StringBuilder更高效。
java正则表达式由Matcher和Pattern提供支持。更常用的是String的一些方法如split(),matches()都可以将正则表达式作为参数接收。
/** * Author: Orisun * Date: Sep 16, 2011 * FileName: Regex.java * Function: */ package Nine; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Regex { public static void main(String[] args){ Pattern pat=Pattern.compile("\\b\\w+@XYZ\\.com\\b"); Matcher mat=pat.matcher("Company Contact Info\n"+ "Tom 555-1111 tom@XYZ.com\n"+ "Marry 555-2222 Mary@XYZ.com\n"+ "Don 555-3333 Don@XYZ.com"); while(mat.find()){ //对find的每次调用都会从上一次停止的位置开始 System.out.println("Match: "+mat.group()); //匹配的字符串在group中 } } } /*********** 输出: Match: tom@XYZ.com Match: Mary@XYZ.com Match: Don@XYZ.com ***********/
正则表达式中除了使用或还可以使用与。[\w && [^A-Z]]匹配大写字母以外的所有单词字符。
+1次或多次
*0次或多次
?0次或1次
+*?都是贪婪量词,它们匹配最长的匹配序列。比如从”simple sample”中匹配模式”s.+e”,则将匹配”simple sample”。贪婪量词后加一个”?“成为胁迫量词,匹配最短的匹配序列,前面的例子”s.+?e”将匹配”simple“。贪婪量词后加一个”+“成为占有量词,匹配最短的匹配序列,不匹配较短的序列,即使它能使整个表达式匹配成功,”s.++e”会匹配失败,因为“.++”将匹配s之后的所有字符,模式是占有的,它不会释放最后的e。
正则表达式中用()来分组,\1是第一个组,\2是第二个组。
正则表达式前加”(?i)”则忽略大小写,”(?i)here”将匹配here,Here及HERE。它也会匹配”there”,因为并没有要求所查找的”here”是一个单独的单词。如果要查找的是整个单词,则要加上词界限定”\b(?i)here\b”。
Java文件处理
Java.util.zip.DeflaterOutputStream
void write(int byteval)
void close()
Java.util.zip.InflaterInputStream
int read()
void close()
以上方法不需要创建压缩文件或解压,而是直接使用标准压缩算法对数据压缩后写入文件,或直接从压缩文件中读出数据。当使用非常大的数据文件时,这是非常有用的。
用java直接创建GZIP文件是简单的,只需要创建GZIPOutputStream,然后向它写入数据即可。创建ZIP会稍微复杂些。一般ZIP文件可以包含一个或多个压缩文件。
对象序列化:将对象写入文件存储之,同时可以读取并恢复这些对象。
因为某个对象可能包含其他对象的引用,因此对象的序列化可能涉及相当复杂的过程。为了将对象序列化它必须实现Serializable接口,这个接口没有定义成员,它只是一个标志。一个可序列化的类的子类都 是可序列化的。但是声明为transient的变量不被序列化工具保存。而且也不保存static变量。因此序列化只保存对象的当前状态。
ObjectOutputStream fout=new ObjectOutputStream(new FileOutputStream(“filename”));
fout.writeObject(obj1);
ObjectInputStream fin=new ObjectInputStream(new FileInputStream(“filename”));
MyClass obj2=(MyClass)fin.readObject();
格式化数据
Formatter fmt=new Formatter();
fmt.format(“Formatter is %s powerful %d %f”,”very”,88,3.14);
String str=fmt.toString();
%g或%G—使用%e或%f中较短的一个
%t或%T—时间或日期
- 左对齐
0 用0而不是用空格填补
%S 字符串大写
n$ n是所需变量的引用,从1开始
fmt.format(“%3$s %1$s %2$d”,”bat”,23,”gama”);
则输出gama 23 bat
fmt.format(“%s in uppercase is %1$S”,”Testing”);
则输出Testing in uppercase is TESTING
使用相对索引“<”允许你重复使用与前面的格式指定符匹配的变量,比如前一例子等价地可以用
fmt.format(“%s in uppercase is %<S”,”Testing”);
Array.fill(charArr,' '); 给一个数组统一赋值
获取当前的日期和时间有两种方式:
1.调用Calendar的静态工厂方法static Calendar getInstance();
2.创建Date对象的一个实例new Date()
通过调用getTimeInMillis()可以从Calendar获得日期和时间的长格式版本,或者调用getTime()从Date获得日期和时间的长格式版本。
Formatter fmt=new Formatter();
Calendar cal=Calendar.getInstance();
fmt.format(Local.GERMAN,”For Local.GERMAN:%tc\n”,cal); 输出德国时间的标准格式
c 标准日期和时间的字符串,格式为:天 月份 日期 hh:mm:ss 年份
Formatter fmtConsole=new Formatter(System.out);
Formatter fmtFile=new Formatter(new FileOutputStream(“filename”));
printf的好处是创建时间戳,在创建日志文件时经常使用。
Static void timeStamp(String msg,PrintWriter
pw){
Calendar cal=Calendar.getInstance();
pw.printf(“%s %tc\n”,msg,cal);
}
PrintWriter pw=new PrintWriter(new FileWriter(“filename”,true));
timeStamp(“File opened”,pw);
Java集合
java5之后所有的API都为了泛型而重新设计。现在志有的集合都是泛型的,并且集合上的操作都接收泛型参数。泛型通过增加类型安全而改进了集合,因为之前的集合都存储object对象,会导致运行时类型不匹配的错误。而使用泛型则显示地指定了数据类型。
利用自动拆装箱可以方便地在集合中存储简单数据类型(比如int是简单数据类型,而Integer就不是)。
上图是接口之间的扩展关系。所有的集合都实现Iterator接口,这意味着可以通过for-each风格的for循环进行遍历。
Collection中的方法:
int hashCode()
boolean retainAll(Collection <?> col) 删除调用集合中除col以外和所有元素
Object[] toArray
<T> T[] toArray( T array[])
List中允许包含重复对象。
ListIterator<E> listIterator() 返回一个失迭代器,指向列表的开始处
ListIterator<E> listIterator(int index) 返回一个失迭代器,指向列表的指定索引位置
Set不允许有重复元素。
SortedSet元素是升序的,从小到大。
Interface SortedSet <E>
E first() 返回第一个(最小的)元素
E last()
SortedSet<E> headSet(E end) 从头部获取小于end的元素
SortedSet<E> Set(E end)
SortedSet<E> subSet(E start,E end)
NavigableSet是java6中新增的,它扩展了SortedSet,基于给定一个值或几个值的最接近匹配。
E ceiling(E obj) 返回>=obj的最小元素
E floor(E obj)
E higher(E obj) 返回>obj的最小元素
E lower(E obj)
Iterator <E> descendingIterator() 返回从大到小移动的迭代器,即反向迭代器。
NavigableSet <E> descendingSet()
NavigableSet <E> headSet(E upperBound,boolean incl) incl为true时等价于ceiling,为false时等价于higher
NavigableSet <E> tailSet(E lowerBound,boolean incl)
NavigableSet <E> subSet(E lowerBound,boolean incl1,E upperBound,boolean incl2)
E pollFirst() 返回并删除第一个元素(亦即最小的元素)
E pollLast()
Deque扩展了Queue,声明双端队列的行为,它最重要的特性是push()和pop(),这使得Deque能像堆栈一样工作。
Void addFirst(E obj)
void addLast(E obj)
上面讲完集合接口,下面讲集合类。
ArrayList实现动态数组,它以初始大小创建,当超过初始大小时,集合会自动增大;当删除对象时,集合会自动缩小。最好设定一个比较大的初始容量,这会防止后续的重新分配内存,因为分配是耗时的。
Void ensureCapacity(int cap)
void trimToSize()
有了ArrayList,Vector逐渐被废弃。
EnumSet用于enum元素。
Class EnumSet <E extends Enum<E>>
LinkedList实现了List和Deque接口。同时因为它采用了双链表结构,可以高效地插入、删除、逆序遍历。
HashSet的构造函数:
HashSet()
HashSet(Collection <? extends E> col)
HashSet(int capacity)
HashSet(int capacity,float fillRatio)
默认情况下填充率fillRatio是0.75。HashSet中的元素不会以任何特定的顺序排列,当用迭代器或for遍历时得到的顺序是未知的。
LinkedHashSet在HashSet的基础之上又采用了双向链表结构,所以列表的顺序和插入的顺序是一致的,同时仍获得哈希化的快速查找的好处。(可以想像它牺牲了多少的空间代价!)
TreeSet中的元素是按升序排列的,同时采用了树结构,所以访问和返回元素非常快,这使得TreeSet对于快速访问大量的存储信息而言是极佳的选择,不过它不允许元素重复。
PriorityQueue创建区分优先权的队列,默认情况下优先权基于元素的自然顺序,但是在构造PriorityQueue时,可以通过指定一个比较器来改变这种顺序。
PriorityQueue(int capacity, Comparator<? Super E> comp)
映射不实现Collection接口,映射中的键和值都必须是对象,不能是基本数据类型。
映射不实现Iterable接口,因此不能用迭代器或for循环遍历,要想这么做需要先获得映射的集合视图。
Map接口 interface Map<K,V>
Boolean containsKey(Object k)
boolean containsValue(Object v)
SortedMap接口是按键的升序排列的。 Interface SortedMap<K,V>
Comparator <? super K> comparator() 返回调用的排序映射比较器。如果使用的是自然排序则返回null。
K firstKey()
K lastKey()
SortedMap<K,V> headMap(K end) <end
SortedMap<K,V> tailMap(K start) >=start
SortedMap<K,V> subMap(K start ,K end) >=start且<end
NavagableMap接口扩展了SortedMap,基于给定一个键或几个键最接近的匹配,类同于NavigableSet和SortedSet的关系。
Map.Entry接口
boolean equals(Object obj)
K getKey()
V getValue()
int hashCode()
V setValue(V v)
常用的映射类有:
HashMap
TreeMap 采用树形结构,实现了NavigableMap。
WeakHashMap 当键不再使用时,允许映射中元素的内存被回收
LinkedHashMap 采用双向链表,允许按插入顺序来迭代
ArrayList<Integer> col=new ArrayList<Integer>();
for(int x:col){}
一般集合可以是任意类型的对象,但对于基于排序的集合,比如PriorityQueue和TreeSet它们的对象必须实现Comparable接口,该接口中定义了compareTo()方法,如果需要,还要重写equals()方法。
ListIterator接口扩展了Iterator接口,可以进行列表的双向遍历和元素的修改,因此ListIterator中有以下方法:
boolean hasPrevious()
E previous()
Collections类中定义了以下算法:
static void reverse(List <?> col) 颠倒列表
static void rotate(List <?> col,int n) 把元素从列表的一端取走,移到另一端
static void shuffle(List <?> col) 随机化元素序列
static <T> int binarySearch(List <? extendsComparable<? Super T>> col,T val) 二分查找
sattic <T extends Comparable<? Super T>> void sort(List <T> col) 排序
当一个线程准备或可能修改一个集合,而另一个线程正好访问这个集合时,就要求同步集合。集合类都不是同步的,如果要创建同步集合,需要使用synchronized方法。
package Nine; import java.util.Collection; import java.util.Collections; import java.util.TreeSet; class MyThread implements Runnable{ Thread t; Collection<String> col; MyThread(Collection<String> c){ col=c; t=new Thread(this,"Second Thread"); t.start(); } public void run(){ try{ Thread.sleep(100); col.add("Omega"); //修改集合 synchronized(col){ //进入临界资源区域,在离开区域之前,本线程独占资源col for(String str:col){ System.out.println("Second Thread:"+str); //读取集合 Thread.sleep(500); } } }catch(InterruptedException exe){ exe.printStackTrace(); } } } public class SyncCollection { public static void main(String[] args){ TreeSet<String> tsStr=new TreeSet<String>(); //tsStr本来不是同步集合 Collection<String> syncCol=Collections.synchronizedCollection(tsStr); //把tsSet设为同步集合 syncCol.add("Gamma"); syncCol.add("Beta"); syncCol.add("Alpha"); new MyThread(syncCol); //启动第二个线程 try{ synchronized(syncCol){ //进入临界资源区域,在离开区域之前,本线程独占资源col for(String str:syncCol){ System.out.println("Main Thread:"+str); //读取集合 Thread.sleep(500); } } }catch(InterruptedException exe){ exe.printStackTrace(); } } }
有时希望保证集合不被修改,比如将集合传递给第三方代码。
Collection<Character> immutableCol=Colleactions.unmodifiableCollection(list);
Properties中的每个键和值都字符串。
Properties prop=new Properties();
prop.setProperty(“Tom”,”tom@hschhildt.com”);
prop.setProperty(“Ken”,”ken@hschhildt.com”);
prop.setProperty(“Steven”,”steven@hschhildt.com”);
//将Properties转换成HashMap
HashMap<String,String> propMap=new HashMap<String,String>((Map) prop);
//将hashMap转换成Set,从而对其元素进行遍历
Set<Map.Entry<String,String>> propSet=propMap.entrySet();
for(Map.Entry<String,String> me:propSet){}
本文来自博客园,作者:高性能golang,转载请注明原文链接:https://www.cnblogs.com/zhangchaoyang/articles/2181383.html