下面以一个简单的示例来帮助读者理解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 阅读(131) |
评论 (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 阅读(79) |
评论 (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 阅读(104) |
评论 (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 阅读(110) |
评论 (0) |
编辑 收藏
Win+R
cmd
sc delete 服务名
posted @
2009-08-09 12:29 jadmin 阅读(93) |
评论 (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 阅读(125) |
评论 (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="http://hi.baidu.com/jadmin">myblog</a>
*/
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 阅读(94) |
评论 (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="http://hi.baidu.com/jadmin">myblog</a>
*/
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 阅读(120) |
评论 (0) |
编辑 收藏