#
package com.sitinspring;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/** *//**
* 用匿名类实现排序的例子
* @author sitinspring(junglesong@gmail.com)
*
* @date 2007-12-7
*/
public class Main{
public static void main(String[] args){
// 新建链表并加入元素
List<Member> members=new ArrayList<Member>();
members.add(new Member("Andy",20));
members.add(new Member("Dell",23));
members.add(new Member("Felex",24));
members.add(new Member("Bill",21));
members.add(new Member("Cindy",22));
// 创建一个比较器匿名类
Comparator comparator=new Comparator(){
public int compare(Object op1,Object op2){
Member memberOp1=(Member)op1;
Member memberOp2=(Member)op2;
// 按姓名排序
return memberOp1.getName().compareTo(memberOp2.getName());
}
};
// 排序
Collections.sort(members,comparator);
// 输出排序后的链表
for(Member member:members){
System.out.println(member);
}
}
}
摘要: 泛型类示例一:
package com.sitinpsring;
import java.util.ArrayList;
import java.util.List;
/** *//**
* 泛型类示例一,成员变量为链表,T可以指代任意类类型.
* @author sitinsprin...
阅读全文
BigDecimal op1=new BigDecimal("3.14159");
BigDecimal op2=new BigDecimal("3");
System.out.println("和="+op1.add(op2));
System.out.println("差="+op1.subtract(op2));
System.out.println("积="+op1.multiply(op1));
System.out.println("商="+op1.divide(op2, BigDecimal.ROUND_UP));
System.out.println("负值="+op1.negate());
System.out.println("指定精度的商="+op1.divide(op2,15, BigDecimal.ROUND_UP));
输出:
和=6.14159
差=0.14159
积=9.8695877281
商=1.04720
负值=-3.14159
指定精度的商=1.047196666666667
Date类内部既不存储年月日也不存储时分秒,而是存储一个从1970年1月1日0点0分0秒开始的毫秒数,而真正有用的年月日时分秒毫秒都是从这个毫秒数转化而来,这是它不容易被使用的地方,尤其是显示和存储的场合。但Date类的优势在于方便计算和比较。
另一点,日常生活中我们习惯用年月日时分秒这样的文本日期来表示时间,它方便显示和存储,也容易理解,但不容易计算和比较。
综上所述,我们在程序中进行日期时间处理时经常需要在在文本日期和Date类之间进行转换,为此我们需要借助java.text.SimpleDateFormat类来进行处理,下文列举了它的几个常用示例。
1.将Date转化为常见的日期时间字符串
这里我们需要用到java.text.SimpleDateFormat类的format方法,其中可以指定年月日时分秒的模式字符串格式。
Date date = new Date();
Format formatter = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");
System.out.println("转化的时间等于="+formatter.format(date));
其中
yyyy表示四位数的年份
MM表示两位数的月份
dd表示两位数的日期
HH表示两位数的小时
mm表示两位数的分钟
ss表示两位数的秒钟
2.将文本日期转化为Date以方便比较
文本日期的优势在于便于记忆,容易处理,但缺点是不方便比较,这时我们需要借助SimpleDateFormat的parse方法得到Date对象再进行比较,实例如下:
String strDate1="2004年8月9日";
String strDate2="2004年10月5日";
SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy年MM月dd日");
java.util.Date date1 = myFormatter.parse(strDate1);
java.util.Date date2 = myFormatter.parse(strDate2);
// Date比较能得出正确结果
if(date2.compareTo(date1)>0){
System.out.println(strDate2+">"+strDate1);
}
// 字符串比较得不出正确结果
if(strDate2.compareTo(strDate1)>0){
System.out.println(strDate2+">"+strDate1);
}
3.将文本日期转化为Date以方便计算
文本日期的另一个大问题是不方便计算,比如计算2008年1月9日的100天后是那一天就不容易,此时我们还是需要把文本日期转化为Date进行计算,再把结果转化为文本日期:
SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy年MM月dd日");
java.util.Date date = myFormatter.parse("2008年1月9日");
date.setDate(date.getDate()+100);
Format formatter = new SimpleDateFormat("yyyy年MM月dd日");
// 得到2008年04月18日
System.out.println("100天后为"+formatter.format(date));
实现类:
package com.sitinspring.view.panel;
import java.awt.Color;
import java.awt.Component;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
/** *//**
* 间隔色表格渲染类
* @author: sitinspring(junglesong@gmail.com)
* @date: 2008-1-10
*/
public class ColorTableCellRenderer extends DefaultTableCellRenderer {
private static final long serialVersionUID = -3378036327580475639L;
public Component getTableCellRendererComponent(
JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
// 得到渲染的单元格
Component cell =
super.getTableCellRendererComponent(
table,
value,
isSelected,
hasFocus,
row,
column);
// 进行渲染
if (hasFocus) {
// 如果获得焦点则设置背景色为红色
cell.setBackground(Color.red);
//cell.setForeground(Color.black);
} else {
if ((row % 2) == 0) {
// 偶数行设置为白色
cell.setBackground(Color.white);
} else {
// 奇数行设置为蓝色
cell.setBackground(Color.cyan);
}
}
return cell;
}
}
package com.sitinspring.view.panel;
import java.awt.Color;
import java.awt.Component;
import java.util.regex.Pattern;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
/** *//**
* 大於37顯示紅色的表單元格
* @author: sitinspring(junglesong@gmail.com)
* @date: 2008-1-10
*/
public class AgeTableCellRenderer extends DefaultTableCellRenderer {
private static final long serialVersionUID = -334535475639L;
public Component getTableCellRendererComponent(
JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
// 得到单元格
Component cell =
super.getTableCellRendererComponent(
table,
value,
isSelected,
hasFocus,
row,
column);
// 先把所有单元格设置为白色
cell.setBackground(Color.white);
// 进行渲染
if (table.getColumnName(column).equals("年龄") ) { // 如果列名等于“年龄”
// 取得单元格的文字
String strValue=(String)value;
if(Pattern.matches("\\d+", strValue)){
if(Integer.parseInt(strValue)>37){
// 如果是数字且值大于37,将单元格背景设置为红色
cell.setBackground(Color.red);
}
}
}
return cell;
}
}
什么是值传递?什么是引用传递?
值传递是将要传递的值作为一副本传递.如
int i=4;
int j=i;
这里相当于把14复制了一个副本给j,结果是i=4,j=4
引用传递,传递的是引用对象的内存地址
int *p,*p1;
int j=5; *p=j; //这里是把j在内存当中的地址赋给了指针p
p1=p; //这里是把指针p中保存的地址(就是j的地址)赋给了指针p1
j=4; //这里改变j的值 输出结果是 j=4 , *p=4 , *p1=4 //因为p和p1指向的都是j 所以他们的值随j值改变
(以上说明和代码来自http://zhidao.baidu.com/question/31191252.html)
Java中函数参数的传递是值传递还是引用传递?
Java中参数传递时传递到函数中的参数都是原变量的一份拷贝,对于非类类型如int,float等,这份拷贝自然和原变量脱离了关系,这不难理解;
而对于类的实例而言,这份拷贝恰巧是实例引用的拷贝,它(参数)指向的实例地址和原实例引用指向的实例地址都是一样的,因此对参数的修改有时也会影响到实例本身,故此造成了Java传递类实例是传递的引用即地址的假象,如下面例子中的changeMemberField函数,但是我们把参数指向的地址改到别的实例上时,如changeMember函数,我们会发现参数和原实例引用再也不会发生关系了,这里证明Java中参数传递是完完全全是传值而不是传址。
例子代码:
代码:
package com.sitinspring;
public class ChangeClass{
public void changeInt(int i){
i=5;
}
public void changeLong(long i){
i=555;
}
public void changeString(String str){
str="5555";
}
public void changeMember(Member member){
member=new Member("Cindy",35);
}
public void changeMemberField(Member member){
member.setAge(20);
member.setName("Andy");
}
public static void main(String[] args){
ChangeClass changeClass=new ChangeClass();
int intValue=10;
changeClass.changeInt(intValue);
System.out.println(intValue);
long longValue=10;
changeClass.changeLong(longValue);
System.out.println(longValue);
String stringValue="1234";
changeClass.changeString(stringValue);
System.out.println(stringValue);
Member member2=new Member("Douglas",45);
changeClass.changeMember(member2);
System.out.println(member2);
Member member=new Member("Bill",25);
changeClass.changeMemberField(member);
System.out.println(member);
}
}
package com.sitinspring;
public class Member{
private String name;
private int age;
public Member(String name,int age){
this.age=age;
this.name=name;
}
public String toString(){
return "Member name="+name+" age="+age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
输出:
10
10
1234
Member name=Douglas age=45
Member name=Andy age=20
解释:
第一个输出10是因为int是基本类型,传递的参数是intValue的拷贝,对拷贝的修改对原值intValue没有影响.
第一个输出10和上面是一个道理.
第三个输出1234.由于String是类类型, str是stringValue的地址拷贝,参数str指向的地址和stringValue的一致,但在函数changeString 中,由于String的特殊性, str=“5555”和str=new String(“5555”)是等价的, str指向了新的”5555”所在的地址,此句后str就与原来的stringValue彻底脱离了联系.
第四个输出Member?name=Douglas?age=45的道理和上面相同.
第五个输出Member?name=Andy?age=20是因为changeMemberField函数中修改了参数member 的值,也就是修改member指向实例的值,而这个实例正是member指向的值,因此member就变成了name=Andy 且age=20.
结论
Java中参数传递的都是值,对应基本类型,传递的是原值的拷贝;对于类类型,传递的是引用即地址的拷贝.
对于函数对参数的改变是否会影响原值的问题:值类型自然不会影响到原值.而对于类类型要看改变的是参数的地址还是值,如果是前者,参数和原引用指向了不同的地址,它们自然脱离了关系;如果是后者,修改的实例就是原引用指向的实例,这当然对原值进行了修改.
代码下载:
http://www.blogjava.net/Files/sitinspring/PassValueOrReference20080116142420.rar
反射Reflection是Java被视为动态语言的一个关键性质.这个机制允许程序在运行时通过Reflection APIs得到任何一个已知名称的类的相关信息,包括其构造方法,父类,实现的接口,成员变量(field)和成员方法(method)的相关信息,并可在运行时改变成员变量的值或调用其方法.反射的高度灵活的特性使得它成为Java语言中最具魔力和活力的部分,它是许多流行框架的实现基础,如Struts,Spring和Hibernate,本篇将列举一些反射常见的API:
实现反射机制的类
在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包中:
Class类:代表一个类。
Field 类:代表类的成员变量(成员变量也称为类的属性)。
Method类:代表类的方法。
Constructor 类:代表类的构造方法。
Array类:提供了动态创建数组,以及访问数组的元素的静态方法。
反射的源头:Class类
Java类继承体系的是一个单根体系,所有类的都起源于Object类,其内声明了数个应该在所有Java class中被改写的methods:hashCode()、equals()、clone()、toString()、getClass()等。其中getClass()返回一个Class object。当一个class被加载,或当加载器(class loader)的defineClass()被JVM调用,JVM 便自动产生一个Class object。
由于在java.lang.Object 类中定义了getClass()方法,因此对于任意一个Java对象,都可以通过此方法获得对象的类型。
Class类对象代表了Java应用程序中的各种类和接口.这些类不是程序代码生成的,而是在Java虚拟机(JVM)装入各种类时生成的.
Static class forName(String className)
这个方法返回以className为名字的Class对象。
Object newInstance()
创建该Class对象代表的类的一个实例,类似调用一个无参数的构造函数。这个方法要求类必须具有一个无参构造函数,如果没有时调用此方法程序会抛出一个java.lang.InstantiationException异常,这也是许多框架要求类具有一个无参构造函数的根本原因
package com.sitinspring;
public class Member{
private String name;
private int age;
private float salary;
public Member(){
name="Unknown";
age=20;
salary=1.00f;
}
public String toString(){
return "名称="+name+" 年龄="+age+" 薪水="+salary;
}
public static void main(String[] args){
try{
Class cls=Class.forName("com.sitinspring.Member");
Member member=(Member)cls.newInstance();
System.out.println(member);
}
catch(Exception ex){
ex.printStackTrace();
}
}
}
Class getSuperclass()
返回该Class对象代表的类的父类。如果该Class是Object,接口,基本数据类型或void,则返回nulll,如果这个类对象是数组,则返回Object类的类对象
public class Member extends Thread implements Comparable{
private String name;
private int age;
private float salary;
public Member(){
name="Unknown";
age=20;
salary=1.00f;
}
public String toString(){
return "名称="+name+" 年龄="+age+" 薪水="+salary;
}
public int compareTo(Object obj){
Member another=(Member)obj;
return this.age-another.age;
}
public static void main(String[] args){
System.out.println(Member.class.getSuperclass());
System.out.println(Object.class.getSuperclass());
System.out.println(Comparable.class.getSuperclass());
System.out.println(int.class.getSuperclass());
System.out.println(void.class.getSuperclass());
System.out.println(String[].class.getSuperclass());
}
}
Class[] getInterfaces()
返回该Class对象实现的接口。
public class Member implements Comparable,Runnable{
private String name;
private int age;
private float salary;
public Member(){
name="Unknown";
age=20;
salary=1.00f;
}
public String toString(){
return "名称="+name+" 年龄="+age+" 薪水="+salary;
}
public int compareTo(Object obj){
Member another=(Member)obj;
return this.age-another.age;
}
public void run(){
}
public static void main(String[] args){
for(Class cls:Member.class.getInterfaces()){
System.out.println(cls.toString());
}
}
}
输出:
interface java.lang.Comparable
interface java.lang.Runnable
Construtor[] getConstructors()
Construtor[] getDeclaredConstructors()
Construtor[] getConstructors(Class[] parameterTypes)
Construtor[] getDeclaredConstructors(Class[] parameterTypes)
返回构造函数,如果有parameterTypes,返回参数类型为parameterTypes的构造函数,Declared是指类中声明的所有构造函数,如果没有Declared,则只返回共有构造函数。
public class Member {
private String name;
private int age;
private float salary;
public Member() {
name = "Unknown";
age = 20;
salary = 1.00f;
}
public Member(String name, int age, float salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
public String toString() {
return "名称=" + name + " 年龄=" + age + " 薪水=" + salary;
}
public static void main(String[] args) {
for (Constructor cls : Member.class.getConstructors()) {
System.out.println(cls.toString());
}
try {
Class cls = Class.forName("com.sitinspring.Member");
Constructor con =cls.getConstructor(new Class[]{String.class, int.class,float.class});
Member member = (Member) con.newInstance(new Object[] {
new String("Sitinspring"), new Integer(30),
new Float(20000) });
System.out.println(member);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Field[] getFields()
Field[] getDeclaredFields()
Field getField(String name)
Field[] getDeclaredFields(String name)
返回成员变量。如果有name参数,返回名字是name的成员变量,Declared指声明中所有的成员变量,如果没有Declared,则只返回公有成员变量。
public class Member {
private String name;
private int age;
private float salary;
public String field1;
protected String field2;
public static void main(String[] args) {
for (Field field : Member.class.getFields()) {
System.out.println(field);
}
for (Field field : Member.class.getDeclaredFields()) {
System.out.println(field.getName());
}
}
}
输出:
public java.lang.String com.sitinspring.Member.field1
name
age
salary
field1
field2
Method[] getMethods()
Method[] getDeclaredMethods()
Method getMethod(String name,Class[] parameterTypes)
Method[] getDeclaredMethods(String name ,Class[] parameterTypes)
返回类的方法,如果有name和parameterTypes参数,返回名字是name,且有parameterTypes参数列表的方法、Declared指声明中所有的方法(包括public,private,protected),如果没有Declared,则只返回公有方法。
Method类有一个重要方法
Object invoke(Object obj,Object[] arg),
通过它可以进行类方法调用,在后面的例子中会见到。
public class Member {
private String name;
private int age;
private float salary;
public Member() {
name = "Unknown";
age = 20;
salary = 1.00f;
}
public String toString() {
return "名称=" + name + " 年龄=" + age + " 薪水=" + salary;
}
public int getAge() {
return age;
}
protected String getName() {
return name;
}
private float getSalary() {
return salary;
}
public static void main(String[] args) {
for (Method method : Member.class.getMethods()) {
System.out.println(method);
}
System.out.println("--------------");
for (Method method : Member.class.getDeclaredMethods()) {
System.out.println(method);
}
}
}
调用类的方法
Method类有一个重要方法
Object invoke(Object obj,Object[] arg),
Object代表返回值,obj是类实例, arg是参数数组。
这个方法能调用实例的一个方法。如右:
public class Caculator{
public int add(int op1,int op2){
return op1+op2;
}
public int substract(int op1,int op2){
return op1-op2;
}
public static void main(String[] args){
try{
Caculator caculator=new Caculator();
Method addMethod = caculator.getClass().getMethod(
"add",
new Class[] { int.class,int.class });
Object result1=addMethod.invoke(caculator, new Object[] { 1,2 });
System.out.println("和="+result1);
Method substractMethod = caculator.getClass().getMethod(
"substract",
new Class[] { int.class,int.class });
Object result2=substractMethod.invoke(caculator, new Object[] { 3,4 });
System.out.println("差="+result2);
}
catch(Exception ex){
ex.printStackTrace();
}
}
}
通过Field对对象进行设值取值请见:
http://www.blogjava.net/sitinspring/archive/2008/01/03/172455.html
通过Method对对象进行设值取值请见:
http://www.blogjava.net/sitinspring/archive/2008/01/05/172970.html
摘要: 费了一番周折,把Tomcat6中JDBC数据源配置好了,这里把过程写一下。感觉是某些网上的东西不可全信,还是官方文档管用。
步骤一:将Oracle的数据库驱动包classes12.jar拷贝到$CATALINA_HOME/lib下,我的Tomcat6库位置是C:\Tomcat6\lib,就拷贝到这里。
步骤二:改写server.xml。
server.xml在$CATALINA_...
阅读全文
通常来说,使用下面的方法确实能改变树节点的图标,但灵活性不高。
// 设定叶节点图标
Icon leafIcon = new ImageIcon(TreeViewPanel.class
.getResource("/leaf.gif"));
// 设定关闭状态节点图标
Icon closedIcon = new ImageIcon(TreeViewPanel.class
.getResource("/close.gif"));
// 设定打开状态节点图标
Icon openIcon = new ImageIcon(TreeViewPanel.class
.getResource("/open.gif"));
// 取得树的渲染器
DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) tree
.getCellRenderer();
// 设定叶节点图标
renderer.setLeafIcon(leafIcon);
// 设定关闭状态节点图标
renderer.setClosedIcon(closedIcon);
// 设定打开状态节点图标
renderer.setOpenIcon(openIcon);
但这样灵活性不高,如我想每层的图标都不一样就不能使用这种方法了,我想要的效果如下:
这时我们只有扩展DefaultTreeCellRenderer创建自己的树节点渲染器,我创建的渲染器代码如下:
package com.sitinspring.common.render;
import java.awt.Component;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeNode;
/** *//**
* 树节点渲染器
* @author: sitinspring(junglesong@gmail.com)
* @date: 2008-2-12
*/
public class TreeNodeRenderer extends DefaultTreeCellRenderer{
private static final long serialVersionUID = 8532405600839140757L;
// 數據庫圖標,頂層節點用
private static final Icon databaseIcon = new ImageIcon(TreeNodeRenderer.class
.getResource("/database.gif"));
// 表圖標,第三層節點用
private static final Icon tableIcon = new ImageIcon(TreeNodeRenderer.class
.getResource("/leaf.gif"));
// 表空間關閉狀態圖標,關閉狀態的第二層節點用
private static final Icon tableSpaceCloseIcon = new ImageIcon(TreeNodeRenderer.class
.getResource("/close.gif"));
// 表空間關閉狀態圖標,打開狀態的第二層節點用
private static final Icon tableSpaceOpenIcon = new ImageIcon(TreeNodeRenderer.class
.getResource("/open.gif"));
public Component getTreeCellRendererComponent(JTree tree,
Object value,
boolean sel,
boolean expanded,
boolean leaf,
int row,
boolean hasFocus){
super.getTreeCellRendererComponent(tree,
value,
sel,
expanded,
leaf,
row,
hasFocus);
// 取得節點
DefaultMutableTreeNode node=(DefaultMutableTreeNode)value;
// 取得路徑
TreeNode[] paths = node.getPath();
// 按路径层次赋予不同的图标
if (paths.length == 3) {
setIcon(tableIcon);
}else if(paths.length == 2){
// 按展開情況再賦予不同的圖標
if(expanded){
setIcon(tableSpaceOpenIcon);
}
else{
setIcon(tableSpaceCloseIcon);
}
}
else if(paths.length == 1){
setIcon(databaseIcon);
}
return this;
}
}
使用这个渲染器使用以下代码就行了:
tree.setCellRenderer(new TreeNodeRenderer());
以上。
摘要: 实例一:
效果图:
页面代码:
Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--><table>
...
阅读全文