#
摘要: 考试分数排序是一种特殊的排序方式,从0分到最高分都可能有成绩存在,如果考生数量巨大如高考,大量考生都在同一分数上,如果需要从低到高排序的话,很多同样分数的成绩也被比较了,这对排序结果是没有意义的,因为同一分数不需要比较,对于这种情况如果使用传统排序就会有浪费,如果先按分数建立好档次,再把考生成绩按分数放入档次就可以了。下面分别列出了三种方案的代码和比较结果:
学生类:
package&nb...
阅读全文
摘要: 成员类:
package com.junglesong;
public class Member implements Comparable{
private String name;
private int&n...
阅读全文
package com.junglesong;
/** *//**
* 二分查找示例
* @author: sitinspring(junglesong@gmail.com)
* @date: 2008-3-8
*/
public class BinSearch{
public static void main(String[] args){
// 欲查找的数组
int[] arr={1,2,3,4,5,6,77,88,656,5000,40000};
// 测试数组
int[] temp={4,5,6,77,88,656,1,2,400};
for(int i:temp){
System.out.println("值"+i+"的下标为"+binSearch(arr,i));
}
}
/** *//**
* 二分查找
* @param sortedArray 已排序的欲查找的数组
* @param seachValue 查找的值
* @return 找到的元素下标,若找不到则返回-1
*/
public static int binSearch(int[] sortedArray,int seachValue){
// 左边界
int leftBound=0;
// 右边界
int rightBound=sortedArray.length-1;
// 当前下标位置
int curr;
while(true){
// 定位在左边界和右边界中间
curr=(leftBound+rightBound)/2;
if(sortedArray[curr]==seachValue){
// 找到值
return curr;
}
else if(leftBound>rightBound){
// 左边界大于右边界,已经找不到值
return -1;
}
else{
if(sortedArray[curr]<seachValue){
// 当当前下标对应的值小于查找的值时,缩短左边界
leftBound=curr+1;
}
else{
// 当当前下标对应的值大于查找的值时,缩短右边界
rightBound=curr-1;
}
}
}
}
}
代码下载:
http://www.blogjava.net/Files/junglesong/BinSearch20080308150836.rar
摘要: 原题(这里使用了数组代替集合)
有两个数组:
String[] arr01={"Andy","Bill","Cindy","Douglas","Felex","Green"};
String[] arr02={"Andy","Bill","Felex","Green","Gates"};
求存在于arr01而不存在于arr02的元素的集合?
最容易想到的解法-双重循环
packag...
阅读全文
适于表现表单的表单元素
Xhtml中提供了一些有用的元素用来在表单中增加结构和定义,它们是fieldset,legend和label。
Fieldset用来给相关的信息块进行分组,它在表现上类似于Swing中的border和VS中的frame。
Legend用来标识fieldset的用户,它相当于border的标题文字。
Label元素可以用来帮助添加结构和增加表单的可访问性,它用来在表单元素中添加有意义的描述性标签。
fieldset,legend和label的例图
页面代码
<form method=post action="#" onsubmit="return checkForm()">
<table width=200 bgcolor="#f8f8f8">
<tr><td>
<fieldset><legend>用户注册</legend>
<p><label for="name">用户名:</label><input type="text" name="name"
value="" /></p>
<p><label for="pswd">密码:</label><input type="text" name="pswd"
value="" /></p>
<p><label for="pswd">再次输入密码:</label><input type="text" name="pswd2"
value="" /></p>
<p><input type="button"
value="注册"/></p>
</fieldset>
</td></tr>
</table>
</form>
未加样式的效果
样式表中的设定
fieldset{
margin:1em 0;
padding:1em;
border:1px solid #ccc;
background:#f8f8f8;
}
legend{
font-weight:bold;
}
label{
display:block;
}
其中值得注意的是label的display属性设置为了block。Label默认是行内元素,但将display属性设置为了block后使其产生了自己的块框,是自己独占一行,因此输入表单就被挤到了下一行,形成了下图的效果。
加入上述样式的效果
More…
表单元素因为输入数据的限制经常宽度不一,当需要个别调整大小是可以这样设置:
<input type="text" name="negetiveinteger"
value="-1" style="width: 200px; height: 20px" />
加入必填字段的标识
在许多表单中有必填字段,我们可以在label中使用Strong来表示出来。代码如下:
<label for="letterOrInteger">ID:<strong class="required">(必填字段)</strong></label>
样式设定如下:
.required{
font-size:12px;
color:#760000;
}
表单反馈效果
表单反馈样式及页面代码
fieldset{
margin:1em 0;
padding:1em;
border:1px solid #ccc;
background:#f8f8f8;
}
legend{
font-weight:bold;
}
label{
width:100px;
}
.feedbackShow{
position:absolute;
margin-left:11em;
left:200px;
right:0;
visibility: visible;
}
.feedbackHide{
position:absolute;
margin-left:11em;
left:200px;
right:0;
visibility: hidden;
}
.required{
font-size:12px;
color:#760000;
}
<table width=100% bgcolor="#f8f8f8">
<tr><td>
<fieldset><legend>员工信息</legend>
<p><label for="letterOrInteger">ID:<strong class="required">(必填字段)</strong></label><span id="idMsg" class="feedbackHide">这里必须输入英语或数字</span><input type="text" name="letterOrInteger"
value="" style="width: 200px; height: 20px" /></p>
<p><label for="character">姓名:</label><span id="nameMsg" class="feedbackHide">这里必须输入汉字</span><input type="text" name="character"
value="" style="width: 200px; height: 20px" /></p>
<p><label for="email">邮件:</label><span id="emailMsg" class="feedbackHide">这里必须输入符合邮件地址的格式</span><input type="text" name="email"
value="" style="width: 200px; height: 20px" /></p>
<p><input type="submit"
value="提交" style="width: 100px; height: 25px"/></p>
</fieldset>
</td></tr>
</table>
JavaScript验证代码
/**
* 检查验证
*/
function checkForm(){
// 英数字验证
var letterOrInteger=$("letterOrInteger").value;
if(isLetterOrInteger(letterOrInteger)==false){
$("letterOrInteger").focus();
$("idMsg").className="feedbackShow";
return false;
}
else{
$("idMsg").className="feedbackHide";
}
// 汉字验证
var character=$("character").value;
if(isCharacter(character)==false){
$("character").focus();
$("nameMsg").className="feedbackShow";
return false;
}
else{
$("nameMsg").className="feedbackHide";
}
// 邮件验证
var email=$("email").value;
if(isEmail(email)==false){
$("email").focus();
$("emailMsg").className="feedbackShow";
return false;
}
else{
$("emailMsg").className="feedbackHide";
}
return false;
}
Tomcat示例工程下载:
http://www.blogjava.net/Files/junglesong/CssTest20080305000633.rar
摘要: 分数排序的特殊问题
在java中实现排序远比C/C++简单,我们只要让集合中元素对应的类实现Comparable接口,然后调用Collections.sort();方法即可.
这种方法对于排序存在许多相同元素的情况有些浪费,明显即使值相等,两个元素之间也要比较一下,这在现实中是没有意义的.
典型例子就是学生成绩统计的问题,例如高考中,满分是150,成千上万的学生成绩都在0-150之间,平均一...
阅读全文
1.Collection接口
Java集合类中最基础的接口是Collection,它定义了两个基本方法:
Public interface Collection<E>{
boolean add(E element);
Iterator<E> iterator();
}
add是向Collection中添加一个元素,当添加的内容确实对Collection发生了有效变更的话add方法返回真,否则返回假,比如你向一个Set添加重复的元素时,Set内容不会变化,add方法会返回假。
iterator方法返回实现了Iterator接口的对象,你可以借此对Collection中的内容进行挨个遍历。
2.Iterator接口
Iterator有三个方法:
Public interface Iterator<E>{
E next();
boolean hasNext();
void remove();
}
通过重复调用next方法,你可以挨个遍历Collection中的元素。然而,当遍历到Collection末端时,此方法会抛出一个NoSuchElementException异常,因此在遍历时你就需要hasNext方法和next方法配合使用。 hasNext方法在当前遍历位置后仍有元素时会返回真。配合例子如下:
Collection<String> c=….;
Iterator<String> iterator=c.iterator();
While(iterator.hasNext()){
String str=iterator.next();
…….
}
remove方法能删除上一次调用next时指向的元素,注意不能连续两次调用remove方法,否则会抛出IllegalStateException.
3.Collection接口的其它方法
int size():返回当前存储的元素个数
boolean isEmpty():当集合中没有元素时返回真
boolean contains(Object obj):当集合中有元素和obj值相等时返回真.
boolean containsAll(Collection<?> other):当集合包含另一集合的全部元素时返回真.
bBoolean addAll (Collection<? extends E> other):把其它集合中的元素添加到集合中来,当此集合确实发生变化时返回真.
boolean remove(Object obj):删除一个和obj值相等的元素,当吻合的元素被删除时返回真.
boolean removeAll(Collection<?> other) :从本集合中删除和另一集合中相等的元素,当本集合确实发生变化时返回真.(差集)
void clear():清除集合中的所有元素
boolean retainAll(Collection<?> other) :从本集合中删除和另一集合中不相等的元素,当本集合确实发生变化时返回真.(交集)
Object[] toArray()
返回由集合中元素组成的数组
4.实现了Collection接口的具体类
ArrayList:带下标的队列,增加和收缩时都是动态的.
LinkedList:有序队列,在任意位置插入和删除都是高效的.
HashSet:不存在重复的非排序集合.
TreeSet:自动排序的不存在重复的集合.
LinkedHashSet:保持了插入时顺序的哈希表
PriorityQueue:优先级队列,能有效的删除最小元素.
5.没有重复元素存在的集合HashSet
HashSet通过哈希码来查找一个元素,这比链表的整体查找要迅速得多,但是由此带来的缺陷时它不能保持插入时的顺序.
由于HashSet靠hash码来识别元素,因此它不能包含重复元素,当集合中已经存在值相等的元素时,再次添加同样的元素HashSet不会发生变化.
Set<String> hashSet=new HashSet<String>();
hashSet.add("Andy");
hashSet.add("Andy");
hashSet.add("Bill");
hashSet.add("Cindy");
hashSet.add("Bill");
hashSet.add("Cindy");
Iterator<String> iter=hashSet.iterator();
while(iter.hasNext()){
System.out.println(iter.next());
}
输出:
Cindy
Andy
Bill
6.自动排序的集合 TreeSet
TreeSet和HashSet类似但它值得一提的一点是无论你以何顺序插入元素,元素都能保持正确的排序位置,这时因为TreeSet是以红黑树的形式存储数据,在插入时就能找到正确的位置.注意插入TreeSet的元素都要实现Comparable接口.
例:
SortedSet<String> treeSet=new TreeSet<String>();
treeSet.add("Andy");
treeSet.add("Andy");
treeSet.add("Bill");
treeSet.add("Cindy");
treeSet.add("Bill");
treeSet.add("Cindy");
Iterator<String> iter=treeSet.iterator();
while(iter.hasNext()){
System.out.println(iter.next());
}
输出:
Andy
Bill
Cindy
7.优先级队列PriorityQueue
PriorityQueue使用一种名为堆的二叉树高效的存储数据,它检索数据是按排序的顺序而插入则随意,当你调用remove方法时,你总能得到最小的元素.但PriorityQueue并不按序排列它的元素,当你遍历时它是不会排序的,这也没有必要. 在制作一个按优先级执行日程安排或事务安排时你应该首先想到PriorityQueue。
例:
PriorityQueue<String> pq=new PriorityQueue<String>();
pq.add("Cindy");
pq.add("Felix");
pq.add("Andy");
pq.add("Bill");
Iterator<String> iter=pq.iterator();
while(iter.hasNext()){
System.out.println(iter.next());
}
while(!pq.isEmpty()){
System.out.println(pq.remove());
}
8.保持插入顺序的哈希表LinkedHashMap
从1.4起Java集合类中多了一个LinkedHashMap,它在HashMap的基础上增加了一个双向链表,由此LinkedHashMap既能以哈希表的形式存储数据,又能保持查询时的顺序.
Map<String,String> members=new LinkedHashMap<String,String>();
members.put("001", "Andy");
members.put("002", "Bill");
members.put("003", "Cindy");
members.put("004", "Dell");
Iterator<String> iter=members.keySet().iterator();
while(iter.hasNext()){
System.out.println(iter.next());
}
Iterator<String> iter2=members.values().iterator();
while(iter2.hasNext()){
System.out.println(iter2.next());
}
9.自动按键进行排序的哈希表TreeMap
Map<String,String> members=new TreeMap<String,String>();
members.put("001", "Andy");
members.put("006", "Bill");
members.put("003", "Cindy");
members.put("002", "Dell");
members.put("004", "Felex");
for(Map.Entry<String,String> entry:members.entrySet()){
System.out.println("Key="+entry.getKey()+" Value="+entry.getValue());
}
10.1 集合工具类Collections的方法unmodifiable
此方法构建一个不可更改的集合视图,当使用其修改方法时会抛出一个UnsupportedOperationException
static Collection<E> unmodifiableCollection(Collection<E> c)
static List<E> unmodifiableList (List<E> c)
static Set<E> unmodifiableSet (Set<E> c)
static SortedSet<E> unmodifiableSortedSet (SortedSet<E> c)
static Map<K,V> unmodifiableMap (Map<K,V> c)
static SortedMap<K,V> unmodifiableSortedMap (SortedMap<K,V> c)
10.2 集合工具类Collections的方法synchronized
此方法会返回一个线程安全的集合视图
static Collection<E> synchronizedCollection(Collection<E> c)
static List<E> synchronizedList (List<E> c)
static Set<E> synchronizedSet (Set<E> c)
static SortedSet<E> synchronizedSortedSet (SortedSet<E> c)
static Map<K,V> synchronizedMap (Map<K,V> c)
static SortedMap<K,V> synchronizedSortedMap (SortedMap<K,V> c)
集合类静态类图
使用表格渲染器渲染表格
在使用JTable时,用户往往希望改变它缺省的渲染方式,比如使用间隔色的行,对特定的单元格进行特殊颜色显示等,这对一些可视化编程环境的表格并不是一件容易的事。
在Java Swing编程中我们可以使用DefaultTableCellRenderer的子类渲染表格来达到这个目的,实现和使用它都非常容易。
渲染效果一:
步骤一:实现一个javax.swing.table.DefaultTableCellRenderer的子类
/**
* 间隔色表格渲染类
*/
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;
}
}
步骤二:将ColorTableCellRenderer设置为表格的渲染器
try {
ColorTableCellRenderer cellRender = new ColorTableCellRenderer();
table.setDefaultRenderer(Class.forName("java.lang.Object"),
cellRender);
} catch (Exception e) {
e.printStackTrace();
}
实现一个将特定单元格设置为红色的表格渲染器
如右,如果想将成员年龄大于37的单元格设置为红色。
AgeTableCellRenderer的代码
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;
}
}
树和节点的基本概念
树可以用图形的方式显示众多的节点以及它们之间的关系,最常见的树的例子就是目录树。
所有组成树的元素都成为节点(Node),一棵树的最顶层的节点称为根节点,如Program;而没有子节点的节点成为叶子节点,如domain。在层次结构中,上层的节点是下层节点的父节点,而下层节点是上层节点的子节点,如图:Program是C# Programs和Programs的父节点;FileBatchRemaer20070801094605是C# Programes的子节点。
有关树JTree的类和接口
JTree 显示树的核心基本类。
TreeModel 定义了树的数据模型接口
DefaultTreeModel 默认的树模型接口实现类
TreeModelListener 树模型的事件监听器
TreePath 树路径。一个路径就是一个对象数组,对应于树模型中从根节点到选定节点上的所有节点集合。数组的第一个元素是根节点,按树的层次关系依次在数组中给出中间节点,最后一个元素是选定的节点。
MutableTreeNode 树节点接口。对应树中的节点。树节点接口定义了与父子节点有关的方法。因此,利用树节点可以遍历整棵树。
DedaultMutableTreeNode 默认的树节点的实现类。
TreeSelectionModel 定义了在树上的选择节点的数据模型接口。树选择模型决定了选择节点的策略以及被选择节点的信息。
TreeSelectionModelListener 树选择模型事件的监听器。
代码实例:构建一棵树
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Java");
DefaultMutableTreeNode j2seNode=new DefaultMutableTreeNode("J2SE(JavaSE)");
DefaultMutableTreeNode swingNode=new DefaultMutableTreeNode("Swing");
DefaultMutableTreeNode socketNode=new DefaultMutableTreeNode("Socket");
DefaultMutableTreeNode threadNode=new DefaultMutableTreeNode("Thread");
j2seNode.add(swingNode);
j2seNode.add(socketNode);
j2seNode.add(threadNode);
DefaultMutableTreeNode j2eeNode=new DefaultMutableTreeNode("J2EE(JavaEE)");
DefaultMutableTreeNode jspservletNode=new DefaultMutableTreeNode("Jsp/Servlet");
DefaultMutableTreeNode jdbcNode=new DefaultMutableTreeNode("JDBC");
DefaultMutableTreeNode javaMailNode=new DefaultMutableTreeNode("Java Mail");
j2eeNode.add(jspservletNode);
j2eeNode.add(jdbcNode);
j2eeNode.add(javaMailNode);
root.add(j2seNode);
root.add(j2eeNode);
tree = new JTree(root);
相关语句解释
// 创建一个树节点,文字为J2SE(JavaSE)
DefaultMutableTreeNode j2seNode=new DefaultMutableTreeNode("J2SE(JavaSE)");
// 创建一个文字为“Swing”的节点,添加在节点j2seNode下
DefaultMutableTreeNode swingNode=new DefaultMutableTreeNode("Swing");
j2seNode.add(swingNode);
// 创建一个文字为Java的节点作为根节点,然后以此根节点构建一棵树。j2seNode,j2eeNode挂在root 下
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Java");
.......
root.add(j2seNode);
root.add(j2eeNode);
tree = new JTree(root);
注意: JTree和JTextArea,JTable一样,也需要放在一个JScrollPane中。
给树控件添加监听
tree.addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent evt) {
// 取得选择状态变化的所有路径
TreePath[] paths = evt.getPaths();
for (int i=0; i<paths.length; i++) {
// 如果处于选择状态
if (evt.isAddedPath(i)) {
// 将路径转化为节点数组
Object[] nodes=paths[i].getPath();
// 得到最后一个节点,即选择的节点
DefaultMutableTreeNode node=(DefaultMutableTreeNode)nodes[nodes.length-1];
// 输出节点名
System.out.println(node.toString());
}
}
}
});
额外的一点美化工作:渲染节点
// 设定叶节点图标
Icon leafIcon = new ImageIcon(TreePanel.class.getResource("/leaf.gif"));
// 设定关闭状态节点图标
Icon closedIcon = new ImageIcon(TreePanel.class.getResource("/close.gif"));
// 设定打开状态节点图标
Icon openIcon = new ImageIcon(TreePanel.class.getResource("/open.gif"));
// 取得树的渲染器
DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer)tree.getCellRenderer();
renderer.setLeafIcon(leafIcon);// 设定叶节点图标
renderer.setClosedIcon(closedIcon);// 设定关闭状态节点图标
renderer.setOpenIcon(openIcon);// 设定打开状态节点图标