下面以一個簡單的示例來幫助讀者理解OGNL表達式。使用OGNL表達式,需要在www.ognl.org網站下載一個ognl.jar插件包,將該文件復制到classpath路徑下即可。建立一個復合類型,如代碼8.1所示。
代碼8.1定義復合類型
package ch8; import java.util.Date; //團隊類 public class Team { //團隊名稱 private String teamname; //定義團隊人員屬性 private Person person; //團隊人數 private int personnum; //屬性的getter和setter方法 public String getTeamname() { return teamname; } public void setTeamname(String teamname) { this.teamname = teamname; } public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } public int getPersonnum() { return personnum; } public void setPersonnum(int personnum) { this.personnum = personnum; } } //定義人員類 class Person { //姓名 private String name; //年齡 private int age; //人員出生日期 private Date birthday; //屬性的getter和setter方法 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } } |
代碼8.1所示內容定義了兩個復合類型:團隊(team)和人員(person)類型。使用OGNL表達式示例,如代碼8.2所示。
代碼8.2使用OGNL表達式示例
package ch8; import java.util.HashMap; import java.util.Map; import ognl.Ognl; import ognl.OgnlException; public class TestOGNL { public static void main(String[] args) { //定義一個Map對象 Map m = new HashMap(); //定義一個Team對象 Team team1 = new Team(); team1.setTeamname("團隊1"); //定義一個Person對象 Person person1 = new Person(); person1.setName("pla1"); //添加team元素 team1.setPerson(person1); //定義一個Team對象 Team team2 = new Team(); team2.setTeamname("團隊2"); //定義一個Person對象 Person person2 = new Person(); person2.setName("pla2"); //添加team元素 team2.setPerson(person2);
//添加Map元素 m.put("team1", team1); m.put("team2", team2); try { System.out.println(Ognl.getValue("team1.teamname", m)); System.out.println(Ognl.getValue("team2.person.name", m)); System.out.println(Ognl.getValue("teamname", team2)); System.out.println(Ognl.getValue("person.name", team2)); } catch (OgnlException e) { } } } |
代碼8.2所示內容定義了一個Map類型的嵌套屬性,如圖8.1所示。
??
|
圖8.1嵌套屬性示意圖 |
運行該示例,控制器顯示如下信息:
★說明★
OGNL可以使用非常簡單的表達式來訪問多層嵌套屬性,為開發者提供了一個有力的工具。
posted @
2009-08-13 14:25 jadmin 閱讀(136) |
評論 (0) |
編輯 收藏
基本的OGNL語法是十分簡單的,當然OGNL支持豐富的表達式,一般情況下,不用擔心OGNL的復雜性。例如有一個man對象,該對象有一個name屬性,那么使用OGNL來獲得該name屬性可以使用如下表達式:
OGNL表達式的基礎單元稱為導航鏈,簡稱為鏈。一個最簡單的鏈由如下部分組成。
>
屬性名稱:如上述示例中的name。
>
方法調用:hashCode()返回當前對象的hash code。
>
數組元素:listeners[0]返回當前對象的監聽器列表中的第一個元素。
★說明★
OGNL表達式基于OGNL上下文中的當前對象,一個“鏈”將使用上一個“鏈”的處理結果,開發者可以任意擴展該鏈的長度,OGNL沒有限制。
例如,一個OGNL表達式如下:
name.toCharArray()[0].numericValue.toString() |
該表達式將按照如下步驟求值。
(1)獲得OGNL Context中初始對象或者是根對象(root對象)的name對象。
(2)調用toCharArray()方法,返回一個String類型對象。
(3)獲得該String對象的第一個字符。
(4)獲得該字符的numericValue屬性(該字符為一個Character對象,該對象有一個getNumericValue()方法,該方法返回一個Integer類型值)。
(5)將獲得的Integer對象轉換為一個String類型值(使用toString()方法)。
posted @
2009-08-13 13:55 jadmin 閱讀(81) |
評論 (0) |
編輯 收藏
OGNL是Object Graph Navigation Language的縮寫,與JSP,JSF相比,OGNL是一種功能非常強大的針對Java的表達式語言(EL),它可用來讀取和更新Java對象的屬性。
OGNL可以用在以下方面:
- 用做數據綁定語言用來綁定GUI元素(textfield, combobox等)到模型對象
- 用做數據源語言用來映射數據庫表到表模型對象
- 用做數據綁定語言用來綁定web組件到數據模型(
WebOGNL,
Tapestry,
WebWork等)
- 提供類似
Jakarta Commons BeanUtils所提供的功能(讀取Java對象的屬性)
OGNL表達式語法:
Java標準類型:bool類型:true,false
int類型:10, 0xABCD等
long類型:100L
float類型:1.0, 0.5F等
double類型:0.01D
char類型:'A', '\uFFFF'等
字符串類型:"Hello World!"
null
OGNL獨自類型:例:10.01B,相當于java.math.BigDecimal
例:100000H,相當于java.math.BigInteger
OGNL表達式中能使用的操作符號:OGNL表達式中能使用的操作符基本跟Java里的操作符一樣,除了能使用 +, -, *, /, ++, --, ==, !=, = 等操作符之外,還能使用 mod, in, not in等
變量的引用:使用方法:#變量名
例:#this, #user.name
對靜態方法或變量的訪問:@mypkg.MyClass@myVar
@mypkg.MyClass@myMethod()
讀取變量值:例:user.address.countryName
方法調用:例:user.getName()
對象的創建:new java.net.URL("http://localhost/")
List表達式例:{"green", "red", "blue"}
Map表達式例:#{"key1" : "value1", "key2" : "value2", "key3" : "value3"}
對map引用,例:map.key1
等等。
OGNL官方首頁:http://www.ognl.org/OGNL官方文檔 (2.6.9)OGNL Language Guide (2.6.9)附:
OGNL使用例:
- package com.test.ognl; ??
- import java.util.HashMap; ??
- import java.util.List; ??
- import java.util.Map; ??
- ??
- import junit.framework.TestCase; ??
- import ognl.Ognl; ??
- import ognl.OgnlContext; ??
- ??
- public class OgnlTest extends TestCase { ??
- ????public void testGetValue() throws Exception { ??
- ???????? OgnlContext context = new OgnlContext(); ??
- ???????? Book book = new Book("book1"); ??
- ???????? context.put("book", book); ??
- ??
- ????????final String expression = "book.name"; ??
- ???????? Object parseExpression = Ognl.parseExpression(expression); ??
- ???????? assertEquals("book1", Ognl.getValue(parseExpression, context)); ??
- ???????? ??
- ???????? book.setName("book2"); ??
- ???????? assertEquals("book2", Ognl.getValue(parseExpression, context)); ??
- ???? } ??
- ???? ??
- ????public void testSetValue() throws Exception { ??
- ???????? OgnlContext context = new OgnlContext(); ??
- ???????? Book book = new Book("book1"); ??
- ???????? context.put("book", book); ??
- ??
- ????????final String expression = "book.name"; ??
- ???????? Object parseExpression = Ognl.parseExpression(expression); ??
- ???????? Ognl.setValue(parseExpression, context, "book2"); ??
- ???????? assertEquals("book2", book.getName()); ??
- ???? } ??
- ???? ??
- ????public void testCallStaticMethod() throws Exception { ??
- ???????? OgnlContext context = new OgnlContext(); ??
- ??
- ????????final String expression = "@com.test.ognl.Book@test()"; ??
- ???????? Object parseExpression = Ognl.parseExpression(expression); ??
- ???????? assertEquals("Hello World", Ognl.getValue(parseExpression, context)); ??
- ???? } ??
- ???? ??
- ????public void testArray() throws Exception { ??
- ???????? OgnlContext context = new OgnlContext(); ??
- ??
- ????????final String expression = "new int[]{1, 2, 3}"; ??
- ???????? Object parseExpression = Ognl.parseExpression(expression); ??
- ????????int[] ret = (int[]) Ognl.getValue(parseExpression, context); ??
- ??
- ???????? assertEquals(1, ret[0]); ??
- ???????? assertEquals(2, ret[1]); ??
- ???????? assertEquals(3, ret[2]); ??
- ???? } ??
- ??
- ????public void testList() throws Exception { ??
- ???????? OgnlContext context = new OgnlContext(); ??
- ??
- ????????final String expression = "{1, 2, 3}"; ??
- ???????? Object parseExpression = Ognl.parseExpression(expression); ??
- ???????? List ret = (List) Ognl.getValue(parseExpression, context); ??
- ??
- ???????? assertEquals(new Integer(1), ret.get(0)); ??
- ???????? assertEquals(new Integer(2), ret.get(1)); ??
- ???????? assertEquals(new Integer(3), ret.get(2)); ??
- ???? } ??
- ???? ??
- ????public void testMap() throws Exception { ??
- ???????? OgnlContext context = new OgnlContext(); ??
- ??
- ????????final String expression = "#{\"name\" : \"book1\", \"price\" : 10.2}"; ??
- ???????? Object parseExpression = Ognl.parseExpression(expression); ??
- ???????? Map value = (Map) Ognl.getValue(parseExpression, context); ??
- ???????? assertEquals("book1", value.get("name")); ??
- ???????? assertEquals(new Integer(10.2), value.get("price")); ??
- ???? } ??
- } ??
- ??
- class Book { ??
- ????private int name; ??
- ??
- ????public Book(String bookName) { ??
- ????????this.name = bookName; ??
- ???? } ??
- ????public int getName() { ??
- ????????return name; ??
- ???? } ??
- ??
- ????public void setName(int Name) { ??
- ????????this.name = name; ??
- ???? } ??
- ??
- ??????
- ????public static String hello() { ??
- ????????return "Hello World"; ??
- ???? }??
posted @
2009-08-12 18:19 jadmin 閱讀(109) |
評論 (0) |
編輯 收藏
cellspacing ---> 單元格的元素與邊界的距離
cellpadding ---> 單元格與單元格之間的距離
posted @
2009-08-09 19:34 jadmin 閱讀(131) |
評論 (0) |
編輯 收藏
??? 缺省構造函數的問題:base類是父類,derived類是子類,首先要說明的是由于先有父類后有子類,所以生成子類之前要首先有父類。class是由class的構造函數constructor產生的,每一個class都有構造函數,如果你在編寫自己的class時沒有編寫任何構造函數,那么編譯器為你自動產生一個缺省default構造函數。這個default構造函數實質是空的,其中不包含任何代碼。但是一牽扯到繼承,它的問題就出現了。
??? 如果父類base class只有缺省構造函數,也就是編譯器自動為你產生的。而子類中也只有缺省構造函數,那么不會產生任何問題,因為當你試圖產生一個子類的實例時,首先要執行子類的構造函數,但是由于子類繼承父類,所以子類的缺省構造函數自動調用父類的缺省構造函數。先產生父類的實例,然后再產生子類的實例。如下:
class base{
}
class derived extends base{
public static void main(String[] args){
??? derived d=new derived();
}
}
下面我自己顯式地加上了缺省構造函數:
class base{
base(){
??? System.out.println("base constructor");
}
}
class derived extends base{
derived(){
??? System.out.println("derived constructor");
}
public static void main(String[] args){
??? derived d=new derived();
}
}
執行結果如下:說明了先產生base class然后是derived class。
base constructor
derived constructor
我要說明的問題出在如果base class有多個constructor而derived class也有多個constructor,這時子類中的構造函數缺省調用那個父類的構造函數呢?答案是調用父類的缺省構造函數。但是不是編譯器自動為你生成的那個缺省構造函數而是你自己顯式地寫出來的缺省構造函數。
class base{
base(){
??? System.out.println("base constructor");
}
base(int i){
??? System.out.println("base constructor int i");
}
}
class derived extends base{
derived(){
??? System.out.println("derived constructor");
}
derived(int i){
??? System.out.println("derived constructor int i");
}
public static void main(String[] args){
??? derived d=new derived();
??? derived t=new derived(9);
}
}
D:\java\thinking\think6>java derived
base constructor
derived constructor
base constructor
derived constructor int i
如果將base 類的構造函數注釋掉,則出錯。
class base{
// base(){
//??? System.out.println("base constructor");
// }
base(int i){
??? System.out.println("base constructor int i");
}
}
class derived extends base{
derived(){
??? System.out.println("derived constructor");
}
derived(int i){
??? System.out.println("derived constructor int i");
}
public static void main(String[] args){
??? derived d=new derived();
??? derived t=new derived(9);
}
}
D:\java\thinking\think6>javac derived.java
derived.java:10: cannot resolve symbol
symbol : constructor base ()
location: class base
derived(){
?????????? ^
derived.java:13: cannot resolve symbol
symbol : constructor base ()
location: class base
derived(int i){
2 errors
說明子類中的構造函數找不到顯式寫出的父類中的缺省構造函數,所以出錯。
那么如果你不想子類的構造函數調用你顯式寫出的父類中的缺省構造函數怎么辦呢?如下例:
class base{
// base(){
//??? System.out.println("base constructor");
// }
base(int i){
??? System.out.println("base constructor int i");
}
}
class derived extends base{
derived(){
??? super(8);
??? System.out.println("derived constructor");
}
derived(int i){
??? super(i);
??? System.out.println("derived constructor int i");
}
public static void main(String[] args){
??? derived d=new derived();
??? derived t=new derived(9);
}
}
D:\java\thinking\think6>java derived
base constructor int i
derived constructor
base constructor int i
derived constructor int i
super(i)表示父類的構造函數base(i)請大家注意:一個是super(i)一個是super(8)。大家想想是為什么??
結論:
子類如果有多個構造函數的時候,父類要么沒有構造函數,讓編譯器自動產生,那么在執行子類構造函數之前先執行編譯器自動產生的父類的缺省構造函數;要么至少要有一個顯式的缺省構造函數可以讓子類的構造函數調用。
posted @
2009-08-09 13:18 jadmin 閱讀(112) |
評論 (0) |
編輯 收藏
Win+R
cmd
sc delete 服務名
posted @
2009-08-09 12:29 jadmin 閱讀(97) |
評論 (0) |
編輯 收藏
????? java提供finalize()方法,垃圾回收器準備釋放內存的時候,會先調用finalize()。
????? (1).對象不一定會被回收。
????? (2).垃圾回收不是析構函數。
????? (3).垃圾回收只與內存有關。
????? (4).垃圾回收和finalize()都是靠不住的,只要JVM還沒有快到耗盡內存的地步,它是不會浪費時間進行垃圾回收的。
???? 垃圾收集器在進行垃圾收集的時候會自動呼叫對象的finalize方法,用來進行一些用戶自定義的非內存清理工作,因為垃圾收集器不會處理內存以外的東西。所以,有的時候用戶需要定義一些清理的方法,比如說處理文件和端口之類的非內存資源。
????? finalize的工作原理應該是這樣的:一旦垃圾收集器準備好釋放對象占用的存儲空間,它首先調用finalize(),而且只有在下一次垃圾收集過程中,才會真正回收對象的內存.所以如果使用finalize(),就可以在垃圾收集期間進行一些重要的清除或清掃工作.
????? finalize()在什么時候被調用?
????? 有三種情況
????? 1.所有對象被Garbage Collection時自動調用,比如運行System.gc()的時候.
????? 2.程序退出時為每個對象調用一次finalize方法。
????? 3.顯式的調用finalize方法
????? 除此以外,正常情況下,當某個對象被系統收集為無用信息的時候,finalize()將被自動調用,但是jvm不保證finalize()一定被調用,也就是說,finalize()的調用是不確定的,這也就是為什么sun不提倡使用finalize()的原因。
????? 理解finalize( ) 正好在垃圾回收以前被調用非常重要。例如當一個對象超出了它的作用域時,finalize( ) 并不被調用。這意味著你不可能知道何時——甚至是否——finalize( ) 被調用。因此,你的程序應該提供其他的方法來釋放由對象使用的系統資源,而不能依靠finalize( ) 來完成程序的正常操作。
posted @
2009-08-08 23:17 jadmin 閱讀(126) |
評論 (0) |
編輯 收藏
Java版二分查找算法
二分查找算法的目標查找集合應該為有序序列
/*
* @(#)BinarySearch.java 2009-8-8
*
* Copyright (c) 2009 by jadmin. All Rights Reserved.
*/
package algorithm.search;
/**
* 二分查找算法
*
* @author <a href="mailto:jadmin@126.com">jadmin</a>
* @version $Id: BinarySearch.java 2009-8-8 上午05:07:05$
* @see <a href=">
*/
public final class BinarySearch {
public static int find(int[] a, int key) {
?? return find(a, 0, a.length - 1, key);
}
// 非遞歸實現
public static int find(int[] a, int fromIndex, int toIndex, int key) {
?? int low = fromIndex;
?? int high = toIndex;
?? while (low <= high) {
??? // 無符號右移位邏輯運算
??? int mid = (low + high) >>> 1;
??? int midVal = a[mid];
??? if (midVal < key)
???? low = mid + 1;
??? else if (midVal > key)
???? high = mid - 1;
??? else
???? return mid; // key found
?? }
?? return -(low + 1); // key not found.
}
// 遞歸實現
public static int search(int[] a, int fromIndex, int toIndex, int key) {
?? if(fromIndex > toIndex) {
??? return -1;
?? }
?? int mid = (fromIndex + toIndex) >>> 1;
?? if(a[mid] < key) {
??? return search(a, mid + 1, toIndex, key);
?? } else if(a[mid] > key) {
??? return search(a, fromIndex, mid - 1, key);
?? } else {
??? return mid;
?? }
}
posted @
2009-08-08 05:10 jadmin 閱讀(97) |
評論 (0) |
編輯 收藏
題目:1 ~ 1000放在含有1001個元素的數組中,只有唯一的一個元素值重復,其它均只出現一次。每個數組元素只能訪問一次,設計一個算法,將它找出來,不用輔助存儲空間,能否設計一個算法實現?
姑且令該數組為int[] a
解法1:數組累和 - (1+2+3+...+.. + 999 + 1000)= 所求結果
public int find(int[] a) {
??? int t = 1000 * (1000 + 1) / 2; // 1 ~ 1000的累和
??? int sum = 0;
??? for(int i = 0;i < a.length;i++) {
??????? sum += a[i];
??? }
??? return (sum - t);
}
解法2:異或
將所有的數全部異或,得到的結果與1^2^3^...^1000的結果進行異或,得到的結果就是重復數。
但是這個算法雖然很簡單,但證明起來并不是一件容易的事情。這與異或運算的幾個特性有關系。
首先是異或運算滿足交換律、結合律。
所以,1^2^...^n^...^n^...^1000,無論這兩個n出現在什么位置,都可以轉換成為1^2^...^1000^(n^n)的形式。
其次,對于任何數x,都有x^x=0,x^0=x。
所以1^2^...^n^...^n^...^1000 = 1^2^...^1000^(n^n)= 1^2^...^1000^0 = 1^2^...^1000(即序列中除了n的所有數的異或)。
令,1^2^...^1000(序列中不包含n)的結果為T
則1^2^...^1000(序列中包含n)的結果就是T^n。
T^(T^n)=n。
所以,將所有的數全部異或,得到的結果與1^2^3^...^1000的結果進行異或,得到的結果就是重復數。
public int find(int[] a) {
??? int t1 = 0;
??? int t2 = 0;
??? for(int i = 0;i < a.length;i++) {
??????? t1 ^= a[i];
??? }
??? for(int i = 1;i <= 1000;i++) {
??????? t2 ^= i;
??? }
??? return (t1 ^ t2);
}
遺留問題:如果放入數組a中的數為:1000個不連續且互不相同的數(設其組成的數組為n) + 重復數(取自數組n),又如何求取這個重復數呢,要保證算法的效率哦
參考:
http://www.cnblogs.com/myqiao/archive/2009/07/21/1528156.html
http://www.cnblogs.com/myqiao/archive/2009/07/22/1528271.html
posted @
2009-08-08 03:57 jadmin 閱讀(102) |
評論 (0) |
編輯 收藏
/*
* @(#)RandNumberUtil.java 2009-8-8
*
* Copyright (c) 2009 by jadmin. All Rights Reserved.
*/
package com.jsoft.util.random;
/**
* 隨機數輔助類
*
* @author <a href="mailto:jadmin@126.com">jadmin</a>
* @version $Id: RandNumberUtil.java 2009-8-8 上午03:22:37$
* @see <a href=">
*/
public class RandNumberUtil {
/**
* 隨機生成count個不重復的并且介于min和max間的整數
*
* @param min
* @param max
* @param count
* @return
*/
public static int[] generate(int min, int max, int count) {
?? if(min > max) {
??? throw new IllegalArgumentException("參數min必須小于max...");
?? }
?? int n = max - min + 1;
?? if(count > n) {
??? throw new IllegalArgumentException("參數count超出范圍...");
?? }
?? int[] span = new int[n];
?? for (int i = 0, j = min; i < n; i++, j++) {
??? span[i] = j;
?? }
??
?? // 存儲要生成的隨機數
?? int[] target = new int[count];
?? for (int i = 0; i < target.length; i++) {
??? int r = (int)(Math.random() * n);
??? target[i] = span[r];
??? span[r] = span[n - 1];
??? n--;
?? }
?? return target;
}
public static void main(String[] args) {
?? int[] a = generate(12, 68, 9);
?? for(int i : a) {
??? System.out.print(i + " ");
?? }
}
}
posted @
2009-08-08 03:29 jadmin 閱讀(121) |
評論 (0) |
編輯 收藏