﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-庄周梦蝶，孰蝶是我，我是孰蝶？一梦至今，蝶我已难分-随笔分类-C#历程</title><link>http://www.blogjava.net/killme2008/category/19912.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 09 Apr 2007 04:35:15 GMT</lastBuildDate><pubDate>Mon, 09 Apr 2007 04:35:15 GMT</pubDate><ttl>60</ttl><item><title>微软为VS.net添加单元测试功能</title><link>http://www.blogjava.net/killme2008/archive/2007/04/09/109316.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Mon, 09 Apr 2007 00:37:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/04/09/109316.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/109316.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/04/09/109316.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/109316.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/109316.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 开源工具已经有NUnit，微软这次给VS增加的单元测试功能不知道是不是直接借鉴NUnit？不过总也是好事，还集成了静态分析和代码覆盖工具等，值的小小期待下。从这点上看，单元测试已经非常深入人心咯。消息来自<a  href="http://www.infoq.com/cn/news/2007/04/MS-Unit-Testing">infoq中文站</a><br><img src ="http://www.blogjava.net/killme2008/aggbug/109316.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-04-09 08:37 <a href="http://www.blogjava.net/killme2008/archive/2007/04/09/109316.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C#实现二叉查找树</title><link>http://www.blogjava.net/killme2008/archive/2007/04/02/108018.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Mon, 02 Apr 2007 09:29:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/04/02/108018.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/108018.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/04/02/108018.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/108018.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/108018.html</trackback:ping><description><![CDATA[<p>二叉查找树（binary search tree)</p>
<p>1）概念：对于树中的每个节点n，其左子节点中保存的所有数值都小于n保存的数值，右子节点保存的数值都大于n保存的数值。</p>
<p>2）二叉查找树可以实现更为优越的查找性能，主要实现方式有数组和链表结构，相比较而言，链表实现更为容易，因为数组实现删除和添加功能需要移动数组元素（如填补删除空位等）</p>
<br>今天下午在打印问题搞定后用C#实现了一下，比java版本比较有趣的使用C#的delegate来代替遍历二叉树时的visit方法，这样一来可以在遍历时对节点进行你所想要的任何操作。我们知道C#的delegate是类型化的函数指针，而C++的函数指针可以模仿动态语言的闭包或者匿名函数。这里也有这样的味道。<br><br>代码如下，只实现了整数型的，节点定义：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;BSTIntNode<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;value;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;BSTIntNode&nbsp;left;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;BSTIntNode&nbsp;right;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;BSTIntNode(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;value,&nbsp;BSTIntNode&nbsp;left,&nbsp;BSTIntNode&nbsp;right)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;value;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.left&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;left;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.right&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;right;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;BSTIntNode(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;value)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;value;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.left&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.right&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<br>然后定义一个Delegate，作为遍历时的访问方法：<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">delegate</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;Visit(BSTIntNode&nbsp;node);</span></div>
<br>然后就是二叉树的实现，删除算法只实现了复制删除法：<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;BSTIntTree<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">protected</span><span style="color: #000000;">&nbsp;BSTIntNode&nbsp;root;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;Visit&nbsp;visit;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;BSTIntTree()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.root&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;BSTIntNode&nbsp;Search(BSTIntNode&nbsp;node,&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;el)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(node&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(el&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;node.value)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;node;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(el&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;node.value)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;node.left;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;node.right;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">查找</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;BSTIntNode&nbsp;Search(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;el)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;Search(root,&nbsp;el);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">广度优先遍历,利用队列实现,至上而下，至左而右</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;BreadthFirst()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BSTIntNode&nbsp;p&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;root;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Queue&nbsp;queue&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ListQueue();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(p&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;queue.Enqueue(p);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">!</span><span style="color: #000000;">queue.IsEmpty())<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(BSTIntNode)queue.Dequeue();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;visit(p);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(p.left&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;queue.Enqueue(p.left);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(p.right&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;queue.Enqueue(p.right);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">深度优先遍历，递归实现线序，中序和后序<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">先序</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">protected</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;PreOrder(BSTIntNode&nbsp;p)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(p&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;visit(p);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PreOrder(p.left);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PreOrder(p.right);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;PreOrder()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PreOrder(root);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">中序</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">protected</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;InOrder(BSTIntNode&nbsp;p)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(p&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InOrder(p.left);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;visit(p);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InOrder(p.right);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;InOrder()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InOrder(root);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">后序</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">protected</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;PostOrder(BSTIntNode&nbsp;p)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(p&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PostOrder(p.left);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PostOrder(p.right);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;visit(p);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;PostOrder()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PostOrder(root);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">插入节点操作</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;Insert(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;el)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BSTIntNode&nbsp;p&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;root,&nbsp;prev&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">查找节点位置</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(p&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;p;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(p.value&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;el)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;p.right;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;p.left;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(root&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">空树</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;root&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;BSTIntNode(el);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(prev.value&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;el)&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">大于节点，插入右子树</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev.right&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;BSTIntNode(el);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev.left&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;BSTIntNode(el);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">复制删除法的实现，归并删除法可能改变树的高度</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;Delete(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;el)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BSTIntNode&nbsp;node,&nbsp;p&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;root,&nbsp;prev&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">查找节点位置</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(p&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">p.value</span><span style="color: #000000;">!=</span><span style="color: #000000;">el)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;p;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(p.value&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;el)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;p.right;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;p.left;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;p;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(p&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;p.value&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;el)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(node.right&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;node.left;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(node.left&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;node.right;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BSTIntNode&nbsp;temp&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;node.left;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BSTIntNode&nbsp;previous&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;node;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(temp.right&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">查找左字节数的最右子节点</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;previous&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;temp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;temp.right;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node.value&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;temp.value;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(previous&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;node)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;previous.left&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;temp.left;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;previous.right&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;temp.left;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(p&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;root)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;root&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;node;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(prev.left&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;p)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev.left&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;node;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;prev.right&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;node;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(root&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(</span><span style="color: #000000;">"</span><span style="color: #000000;">没有找到节点：{0}</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;el);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(</span><span style="color: #000000;">"</span><span style="color: #000000;">树为空！</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<br>注意，在树中我们维持了一个Visit的delegate，看看使用方法：<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;Main(</span><span style="color: #0000ff;">string</span><span style="color: #000000;">[]&nbsp;args)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BSTIntTree&nbsp;tree</span><span style="color: #000000;">=</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;BSTIntTree();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;[]num</span><span style="color: #000000;">=</span><span style="color: #000000;">{</span><span style="color: #000000;">10</span><span style="color: #000000;">,</span><span style="color: #000000;">20</span><span style="color: #000000;">,</span><span style="color: #000000;">6</span><span style="color: #000000;">,</span><span style="color: #000000;">12</span><span style="color: #000000;">,</span><span style="color: #000000;">23</span><span style="color: #000000;">,</span><span style="color: #000000;">15</span><span style="color: #000000;">,</span><span style="color: #000000;">8</span><span style="color: #000000;">};<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;i&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">;&nbsp;i&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;num.Length;&nbsp;i</span><span style="color: #000000;">++</span><span style="color: #000000;">)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree.Insert(num[i]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">添加遍历处理函数，可以有多个&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree.visit&nbsp;</span><span style="color: #000000;">+=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Visit(printNode);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(</span><span style="color: #000000;">"</span><span style="color: #000000;">广度优先遍历</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree.BreadthFirst();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(</span><span style="color: #000000;">"</span><span style="color: #000000;">先序</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree.PreOrder();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(</span><span style="color: #000000;">"</span><span style="color: #000000;">中序</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree.InOrder();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(</span><span style="color: #000000;">"</span><span style="color: #000000;">后序</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree.PostOrder();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree.Delete(</span><span style="color: #000000;">8</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree.Delete(</span><span style="color: #000000;">15</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(</span><span style="color: #000000;">"</span><span style="color: #000000;">删除后广度优先遍历</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree.BreadthFirst();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">static</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;printNode(BSTIntNode&nbsp;node)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(</span><span style="color: #000000;">"</span><span style="color: #000000;">访问节点:{0}</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;node.value);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<br>
<p>可以看到，C#的delegate机制非常有趣，如果在java中恐怕需要用inner class来实现了。<br></p>
<p><br></p><img src ="http://www.blogjava.net/killme2008/aggbug/108018.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-04-02 17:29 <a href="http://www.blogjava.net/killme2008/archive/2007/04/02/108018.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C#实现栈和队列</title><link>http://www.blogjava.net/killme2008/archive/2007/03/30/107409.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Fri, 30 Mar 2007 01:44:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/03/30/107409.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/107409.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/03/30/107409.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/107409.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/107409.html</trackback:ping><description><![CDATA[有了前一篇<a href="/killme2008/archive/2007/03/29/107261.html">C#链表的实现</a>，实现栈和队列易如反掌。<br /><br />栈，利用单向链表实现：<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">abstract</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> AbstractStack<br />    {<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">abstract</span><span style="color: rgb(0, 0, 0);"> Object Pop();<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">abstract</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> Push(Object obj);<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">abstract</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">bool</span><span style="color: rgb(0, 0, 0);"> IsEmpty();<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">abstract</span><span style="color: rgb(0, 0, 0);"> Object Top();<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">abstract</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> Clear();<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> Stack : AbstractStack<br />    {<br />        </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> SList list;<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> Stack()<br />        {<br />            list </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> SList();<br />        }<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">override</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">bool</span><span style="color: rgb(0, 0, 0);"> IsEmpty()<br />        {<br />            </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> list.IsEmpty();<br />        }<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">override</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> Push(Object obj)<br />        {<br />            list.Push(obj);<br />        }<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">override</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">object</span><span style="color: rgb(0, 0, 0);"> Pop()<br />        {<br />            </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> list.Pop();<br />        }<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">override</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">object</span><span style="color: rgb(0, 0, 0);"> Top()<br />        {<br />            </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> list.getTail();<br />        }<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">override</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> Clear()<br />        {<br />            list.Clear(); <br />        }<br />    }</span></div><br />队列的实现，通过双向链表实现，对于环形数组的实现请参考《<a href="/killme2008/archive/2007/02/20/100239.html">数组结构之栈与链表</a>》：<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">interface</span><span style="color: rgb(0, 0, 0);"> Queue<br />    {<br />        </span><span style="color: rgb(0, 0, 255);">bool</span><span style="color: rgb(0, 0, 0);"> IsEmpty();<br />        </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> Enqueue(Object obj);<br />        Object Dequeue();<br />        Object First();<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> ListQueue:Queue<br />    {<br />        </span><span style="color: rgb(0, 0, 255);">private</span><span style="color: rgb(0, 0, 0);"> LinkedList list;<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> ListQueue()<br />        {<br />            list </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> LinkedList();<br />        }<br /><br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">bool</span><span style="color: rgb(0, 0, 0);"> IsEmpty()<br />        {<br />            </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> list.IsEmpty();<br />        }<br /><br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> Enqueue(Object obj)<br />        {<br />            list.Push(obj);<br />        }<br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> Object Dequeue()<br />        {<br />            </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> list.Shift();<br />        }<br /><br />        </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> Object First()<br />        {<br />            </span><span style="color: rgb(0, 0, 255);">return</span><span style="color: rgb(0, 0, 0);"> list.getHead();<br />        }<br />    }<br /></span></div><br /><img src ="http://www.blogjava.net/killme2008/aggbug/107409.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-03-30 09:44 <a href="http://www.blogjava.net/killme2008/archive/2007/03/30/107409.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C#实现链表</title><link>http://www.blogjava.net/killme2008/archive/2007/03/29/107261.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Thu, 29 Mar 2007 09:02:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/03/29/107261.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/107261.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/03/29/107261.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/107261.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/107261.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: C#实现单向和双向链表。&nbsp;&nbsp;<a href='http://www.blogjava.net/killme2008/archive/2007/03/29/107261.html'>阅读全文</a><img src ="http://www.blogjava.net/killme2008/aggbug/107261.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-03-29 17:02 <a href="http://www.blogjava.net/killme2008/archive/2007/03/29/107261.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>对MarshalByRefObject的解释</title><link>http://www.blogjava.net/killme2008/archive/2007/03/28/107037.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Wed, 28 Mar 2007 09:55:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/03/28/107037.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/107037.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/03/28/107037.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/107037.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/107037.html</trackback:ping><description><![CDATA[    今天看到一段介绍C#实现代理模式的代码，使用到了<span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US">MarshalByRefObject</span><span style="font-size: 10pt; color: black; font-family: 宋体;">。那么</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US">MarshalByRefObject</span><span style="font-size: 10pt; color: black; font-family: 宋体;">到底是什么东西呢？简单来讲，继承此类的对象</span><span style="font-size: 10pt; color: black; font-family: 宋体;">可以跨越应用程序域边界被引用，甚至被远程引用。远程调用时，将产生一个远程对象在本地的透明代理，通过此代理来进行远程调用。一篇很好的解释文章，来自http://dudu.cnblogs.com/archive/2004/03/04/2182.html<br /><br /><br /></span><div class="postText"><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><b style=""><span style="font-size: 10pt; color: black; font-family: 宋体;">问：</span></b><b style=""><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></b></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 宋体;">打扰一下，请问</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US">MarshalByRefObject</span><span style="font-size: 10pt; color: black; font-family: 宋体;">中的</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US">"Marshal"</span><span style="font-size: 10pt; color: black; font-family: 宋体;">应该怎样理解？</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p> </o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><b style=""><span style="font-family: 宋体;">回复</span></b><span style="font-family: 宋体;">：</span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt;"><span style="font-size: 10pt; color: black; font-family: 宋体;">按照</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">package</span><span style="font-size: 10pt; color: black; font-family: 宋体;">的意思理解</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">——</span><span style="font-size: 10pt; color: black; font-family: 宋体;">当一个对象需要长途跋涉到另一个环境中时，需要将其</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">marshal</span><span style="font-size: 10pt; color: black; font-family: 宋体;">成一个可以传输的形态（比如在</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">.NET Remoting</span><span style="font-size: 10pt; color: black; font-family: 宋体;">中对象将被打包成一个</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">serializable</span><span style="font-size: 10pt; color: black; font-family: 宋体;">的</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">ObjRef</span><span style="font-size: 10pt; color: black; font-family: 宋体;">实例</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">——</span><span style="font-size: 10pt; color: black; font-family: 宋体;">这个</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">ByRef</span><span style="font-size: 10pt; color: black; font-family: 宋体;">就是指</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">ObjRef</span><span style="font-size: 10pt; color: black; font-family: 宋体;">这种形态）；同理，当打包以后传输到目标地点，还要执行</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">unmarshal</span><span style="font-size: 10pt; color: black; font-family: 宋体;">的操作将其还原为内存中的对象。：）</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US"><o:p> </o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><b style=""><span style="font-size: 10pt; color: black; font-family: 宋体;">问：</span></b><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span style="font-size: 10pt; color: black; font-family: 宋体;">谢谢！</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US">MarshalByRefObject</span><span style="font-size: 10pt; color: black; font-family: 宋体;">是不是可以这样理解：对被引用的对象进行</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US">Marshal</span><span style="font-size: 10pt; color: black; font-family: 宋体;">。如果按照</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US">package</span><span style="font-size: 10pt; color: black; font-family: 宋体;">的意思理解，那</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US">package</span><span style="font-size: 10pt; color: black; font-family: 宋体;">的过程是怎样的？</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"> <o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><b><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US">MSDN</span></b><b><span style="font-size: 10pt; color: black; font-family: 宋体;">上这样讲：</span></b><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><b><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US">MarshalByRefObject</span></b><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"></span><span style="font-size: 10pt; color: black; font-family: 宋体;">是通过使用</span><span style="font-size: 10pt; color: red; font-family: 宋体;">代理</span><span style="font-size: 10pt; color: black; font-family: 宋体;">交换消息来跨应用程序域边界进行通讯的对象的基类</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US">.<o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><b><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US">MarshalByRefObject</span></b><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"></span><span style="font-size: 10pt; color: black; font-family: 宋体;">对象在本地应用程序域的边界内可直接访问。远程应用程序域中的应用程序首次访问</span><b><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US">MarshalByRefObject</span></b><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"></span><span style="font-size: 10pt; color: black; font-family: 宋体;">时，会向该远程应用程序传递</span><span style="font-size: 10pt; color: red; font-family: 宋体;">代理</span><span style="font-size: 10pt; color: black; font-family: 宋体;">。对该代理后面的调用将封送回驻留在本地应用程序域中的对象。</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"> <o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 宋体;">在</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US">Marshal</span><span style="font-size: 10pt; color: black; font-family: 宋体;">中，上面所说的代理是什么？有什么用？</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"> <o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><b><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US">MSDN</span></b><b><span style="font-size: 10pt; color: black; font-family: 宋体;">上还讲到：</span></b><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 宋体;">当跨应用程序域边界使用类型时，类型必须是从</span><span style="font-size: 10pt; color: black; font-family: Verdana;"><b><span lang="EN-US">MarshalByRefObject</span></b><span lang="EN-US"></span></span><span style="font-size: 10pt; color: black; font-family: 宋体;">继承的，而且由于对象的成员在创建它们的应用程序域之外无法使用，所以</span><span style="font-size: 10pt; color: red; font-family: 宋体;">不得复制对象的状态</span><span style="font-size: 10pt; color: black; font-family: 宋体;">。</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"> <o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 宋体;">既然对象的状态不能传递过去，那传递这个对象又有何意义？</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 宋体;">第一次去理解</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US">MarshalByRefObject</span><span style="font-size: 10pt; color: black; font-family: 宋体;">，有的问题可能提的比较肤浅，请您指点。</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><o:p> </o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><b style=""><span style="font-family: 宋体;">回复：</span></b><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt;"><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">MarshalByRefObject</span><span style="font-size: 10pt; color: black; font-family: 宋体;">是所有可以在</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">AppDomain</span><span style="font-size: 10pt; color: black; font-family: 宋体;">边界外部访问的对象的基类，重心不是</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">marshal</span><span style="font-size: 10pt; color: black; font-family: 宋体;">，而是</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">object</span><span style="font-size: 10pt; color: black; font-family: 宋体;">，即</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">object that could be marshaled by reference</span><span style="font-size: 10pt; color: black; font-family: 宋体;">，也就是可以通过</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">Ref</span><span style="font-size: 10pt; color: black; font-family: 宋体;">（实际上是</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">ObjRef</span><span style="font-size: 10pt; color: black; font-family: 宋体;">对象）的机制进行</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">“</span><span style="font-size: 10pt; color: black; font-family: 宋体;">封送</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">”</span><span style="font-size: 10pt; color: black; font-family: 宋体;">（</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">MSDN</span><span style="font-size: 10pt; color: black; font-family: 宋体;">中文版对</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">marshal</span><span style="font-size: 10pt; color: black; font-family: 宋体;">一词的翻译）的对象。封送的行为是由代理来做的，这里说的代理就是我文章中讲过的</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">.NET Remoting</span><span style="font-size: 10pt; color: black; font-family: 宋体;">的真实代理（即</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">RemotingProxy</span><span style="font-size: 10pt; color: black; font-family: 宋体;">）。真实代理不是有一个</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">Invoke()</span><span style="font-size: 10pt; color: black; font-family: 宋体;">方法吗？当你透过对一个</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">MBRO</span><span style="font-size: 10pt; color: black; font-family: 宋体;">的透明代理访问该对象的方法时，透明代理将把基于堆栈的方法调用转换为方法调用消息（</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">IMethodCallMessage</span><span style="font-size: 10pt; color: black; font-family: 宋体;">）并转发给真实代理（在</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">Remoting</span><span style="font-size: 10pt; color: black; font-family: 宋体;">的场合中也即</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">RemotingProxy</span><span style="font-size: 10pt; color: black; font-family: 宋体;">），而</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">RemotingProxy</span><span style="font-size: 10pt; color: black; font-family: 宋体;">的任务就是把对象封送并连同方法调用消息一起转发给远程应用程序域；到达目的地以后的操作类似：远程应用程序域中的监听方当收到发来的方法调用消息时，先取出封送好的</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">ObjRef</span><span style="font-size: 10pt; color: black; font-family: 宋体;">（这个对象里面保存着发来调用的那个对象！），将其结封（</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">unmarshal</span><span style="font-size: 10pt; color: black; font-family: 宋体;">）为本地的对象，并获得其透明代理，然后就可以把方法调用消息在转换回基于堆栈的调用发送给这个对象。</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"> <o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 宋体;">对象是在本地维护的，但是方法可以在远程调用。你比如说一个</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">web</span><span style="font-size: 10pt; color: black; font-family: 宋体;">应用程序，你是通过本地的浏览器远程访问这个应用程序，但是应用程序的状态不会由你的浏览器负责（所以你只是在访问这个应用程序提供给你的功能而已，你并没于拥有应用程序本身，包括其所有数据），你只是发送一个个的请求，服务器告诉你处理的结果。在</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">Remoting</span><span style="font-size: 10pt; color: black; font-family: 宋体;">中
也是一样，当你获得一个远程对象的时候，你实际上只拥有对这个对象的一个远程引用，虽然你可以调用它的方法，但实际上这些操作都是发生在远程的（就是前面
讲过的过程），你只是传入了一些参数，得到了一个结果，但对象的状态还是在远程维护的（换句话说，对象本身也就是对象的所有状态并没有被往返传递，传递的
只是传入传出的参数</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">——</span><span style="font-size: 10pt; color: black; font-family: 宋体;">当然，如果参数是一个</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">MBRO</span><span style="font-size: 10pt; color: black; font-family: 宋体;">的话，还是传递对象被封送的引用）。</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"> <o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-indent: 21pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 宋体;">也许应该给你准备一个好理解的例子</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">……</span><span style="font-size: 10pt; color: black; font-family: 宋体;">你就会豁然开朗了。：）</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><o:p> </o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><b style=""><span style="font-size: 10pt; color: black; font-family: 宋体;">问：</span></b><b style=""><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></b></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 宋体;">我这样的理解对不对？</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 宋体;">一般的对象与从</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US">MarshalByRefObject</span><span style="font-size: 10pt; color: black; font-family: 宋体;">继承的对象区别是：</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 宋体;">一般的对象只能在本地应用程序域之内被引用，而</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US">MarshalByRefObject</span><span style="font-size: 10pt; color: black; font-family: 宋体;">对象可以跨越应用程序域边界被引用，甚至被远程引用。</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><span lang="EN-US"><o:p> </o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt;"><b style=""><span style="font-family: 宋体;">回复</span></b><span style="font-family: 宋体;">：</span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">Exactly! </span><span style="font-size: 10pt; color: black; font-family: 宋体;">当对象跨出</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">AppDomain</span><span style="font-size: 10pt; color: black; font-family: 宋体;">边界的时候，实际上只是它的一个引用（</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">ObjRef</span><span style="font-size: 10pt; color: black; font-family: 宋体;">）。你比如说吧：</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"> <o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">public class LocalObject<br />{</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">  public void CallRemoteObject(MarshalByRefObject mbro)<br />  {<br />    Console.WriteLine(mbro.ToString());</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">  }<br />}</span><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p><p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: Verdana;" lang="EN-US"> <o:p></o:p></span></p><span style="font-size: 10pt; color: black; font-family: 宋体;">当传入一个在本地创建的</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">mbro</span><span style="font-size: 10pt; color: black; font-family: 宋体;">对象时，</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">ToString()</span><span style="font-size: 10pt; color: black; font-family: 宋体;">方法是直接发送给对象的；而当</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">mbro</span><span style="font-size: 10pt; color: black; font-family: 宋体;">是通过</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">Remoting</span><span style="font-size: 10pt; color: black; font-family: 宋体;">创建的远程对象的话，实际上它只是一个包含有已经</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">marshal</span><span style="font-size: 10pt; color: black; font-family: 宋体;">好的</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">ObjRef</span><span style="font-size: 10pt; color: black; font-family: 宋体;">的透明代理，</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">ObjRef</span><span style="font-size: 10pt; color: black; font-family: 宋体;">里面有什么？对象实例的</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">URI</span><span style="font-size: 10pt; color: black; font-family: 宋体;">！所以当你调用这个远程对象时，相当于向这个远程端口（</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">tcp://remoteServer/xxxx.rem</span><span style="font-size: 10pt; color: black; font-family: 宋体;">）发送方法调用消息而已。只不过透明代理隐藏了对象位置的概念，而</span><span style="font-size: 10pt; color: black; font-family: Arial;" lang="EN-US">RemotingProxy</span><span style="font-size: 10pt; color: black; font-family: 宋体;">真实代理则是实际上处理远程方法调用和对象封送的中枢对象。</span></div><br /><img src ="http://www.blogjava.net/killme2008/aggbug/107037.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-03-28 17:55 <a href="http://www.blogjava.net/killme2008/archive/2007/03/28/107037.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>体验rails1.2的REST风格</title><link>http://www.blogjava.net/killme2008/archive/2007/03/20/105083.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Tue, 20 Mar 2007 12:04:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/03/20/105083.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/105083.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/03/20/105083.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/105083.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/105083.html</trackback:ping><description><![CDATA[    REST这个名词已经听过许久，在javaeye的ruby版上也看到不少的讨论，一开始是搞不明白的，似乎跟webservice有关。今天读了《RESTfull Rails Development》和几篇介绍REST的文章开始有点明白。REST 是英文 Representational State Transfer 的缩写，有中文翻译为“具象状态传输”。读这篇文章《<a href="http://www.duduwolf.com/wiki/2007/260.html">学习REST</a>》对于初次接触REST的人来说更好理解。<p>    我们在 Web 应用中处理来自客户端的请求时，通常只考虑 GET 和 POST 这两种 HTTP 请求方法。实际上，HTTP 还有
HEAD、PUT、DELETE 等请求方法。而在 REST 架构中，用不同的 HTTP 请求方法来处理对资源的
CRUD（创建、读取、更新和删除）操作：</p><ul><li>POST: 创建 </li><li>GET: 读取 </li><li>PUT: 更新 </li><li>DELETE: 删除 </li></ul><p>经过这样的一番扩展，我们对一个资源的 CRUD 操作就可以通过同一个 URI 完成了。需要注意的是REST的核心就是资源（resources）这个概念。我们所说的webservice是一种建立在http协议上的远程调用，而REST就是把远程调用抽象成对远程资源的CRUD的操作，正好可以用HTTP的PUT GET POST DELETE来对应，而不是重新发明一个协议（比如soap，简单对象访问协议）。REST与AJAX的流行，甚至远至设计模式的兴起，都充分说明一个现象，在成熟的应用的基础上创新而非扩展出复杂所谓“创新性”架构在软件行业是更为可靠。</p><p>    实战体验REST可以从IBM Developer的这篇文章开始《<a href="http://www.ibm.com/developerworks/cn/java/j-cb08016/">跨越边界：Rest On Rails</a>》。这篇文章是在Rails1.2发布之前出来的，有些地方已经可以修改的更简练，我把我的练习过程记录下，并添加了C#调用REST风格web service的例子。</p><p>    首先，你的机器上需要安装rails1.2，并且假设你对rails有基本的了解，建立一个应用叫service,命令行执行：</p><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">   <div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);"> rails service</span></div><br /></span><p>rails自动帮你生成应用的基本结构和基础代码，然后编辑config下面的database.yml设置数据库，并建立数据service_development，我用的是mysql数据库。</p><p><img src="http://www.blogjava.net/images/blogjava_net/killme2008/create.bmp" alt="create.bmp" border="0" height="400" width="640" /><br /></p><p>利用rails1.2新的scaffold命令：</p><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">ruby script</span><span style="color: rgb(128, 128, 128);">/</span><span style="color: rgb(0, 0, 0);">generate scaffold_resource person</span></div><p>这个命令将自动生成ActiveRecord,Controller以及View，在\app\models下可以发现自动生成的Model——person.rb。打开service\db\migrate下面的001_create_people.rb，编辑如下：</p><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">class CreatePeople </span><span style="color: rgb(0, 0, 0);">&lt;</span><span style="color: rgb(0, 0, 0);"> ActiveRecord</span><span style="color: rgb(0, 0, 0);">::</span><span style="color: rgb(0, 0, 0);">Migration<br />  def self</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">up<br />    create_table </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">people </span><span style="color: rgb(0, 0, 255);">do</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">|</span><span style="color: rgb(0, 0, 0);">t</span><span style="color: rgb(0, 0, 0);">|</span><span style="color: rgb(0, 0, 0);"><br />     t</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">column </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">first_name</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">string</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">limit </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">40</span><span style="color: rgb(0, 0, 0);"><br />     t</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">column </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">last_name</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">string</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">limit </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">40</span><span style="color: rgb(0, 0, 0);"><br />     t</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">column </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">email</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">string</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">limit </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">40</span><span style="color: rgb(0, 0, 0);"><br />     t</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">column </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">phone</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">string</span><span style="color: rgb(0, 0, 0);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">limit </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">15</span><span style="color: rgb(0, 0, 0);"><br />    end<br />  end<br /><br />  def self</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">down<br />    drop_table </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">people<br />  end<br />end<br /></span></div><br />利用rake命令自动建表，执行 <br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">rake db</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">migrate</span></div>rails默认表明是Model的复数形式，也就是这里将自动建立一张名叫people的表。<br /><br />OK，一切就绪，启动WEBric，访问http://localhost:3000/people，显示：<br /><img src="http://www.blogjava.net/images/blogjava_net/killme2008/rest1.bmp" alt="rest1.bmp" border="0" height="725" width="539" /><br /><br />scaffold已经帮我们自动生成了一个对person资源的crud操作，增删改查似乎跟传统的rails没有什么不同嘛。如果你认真观察在操作过程中URL的变化情况就会发现在操作过程中URL的变化很小，而且与传统rails的URL路由相比，省去了action名称。出现的变化在/people、/people/1、/people/1;edit和/people/new这几个之中。在/people的URL中隐藏这可能是http的POST或者GET的方法，前者用于create操作，而GET用于show操作，具体你可以查看app/controllers/目录下的PeopleController类，每个action的前面都注释了它们将对应哪个HTTP方法。而/people/1中的1指的是资源的标志符，比如这里person的id，通过这个ID来进行资源的操作，也许是PUT方法（更新），也许是DELETE方法（删除）。rails实现PUT和Delete是通过隐藏字段来实现的，查看编辑页面生成的html源代码，你将发现一个_method的隐藏字段，值为PUT。而另外两个URL：/people/1;edit和/people/new，这两个并非严格意义上的RESTful URL，它们只是为了显示用，显示form表单用于新建和编辑。关于RESTful风格的URL的详细讨论请见《RESTfull Rails Development》文档。<br /><br />    如果rails只是这样的威力，那就有点小提大做了，看看PeopleController的show action，它对应于http的GET请求，返回people列表：<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);"> GET /people/1<br />  # GET /people/1.xml</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">  def show<br />    </span><span style="color: rgb(128, 0, 128);">@person</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Person</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">find(params[</span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">id])<br /><br />    respond_to </span><span style="color: rgb(0, 0, 255);">do</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">|</span><span style="color: rgb(0, 0, 255);">format</span><span style="color: rgb(0, 0, 0);">|</span><span style="color: rgb(0, 0, 0);"><br />      </span><span style="color: rgb(0, 0, 255);">format</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">html </span><span style="color: rgb(0, 128, 0);">#</span><span style="color: rgb(0, 128, 0);"> show.rhtml</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">      </span><span style="color: rgb(0, 0, 255);">format</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">xml  { render </span><span style="color: rgb(0, 0, 0);">:</span><span style="color: rgb(0, 0, 0);">xml </span><span style="color: rgb(0, 0, 0);">=&gt;</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 128);">@person</span><span style="color: rgb(0, 0, 0);">.</span><span style="color: rgb(0, 0, 0);">to_xml }<br />    end<br />  end</span></div><br />神奇的地方在respond_to方法中，根据请求文件类型（http Header的ContentType），显示html格式，或者xml格式（还有其他支持，比如json、RSS、Atom等等）。比如你添加了一个person,通过http://localhost:3000/people/1访问，可以看到这个人员的具体信息：<br /><img src="http://www.blogjava.net/images/blogjava_net/killme2008/rest2.bmp" alt="rest2.bmp" border="0" height="232" width="262" /><br />我们再通过http://localhost:3000/people/3.xml访问看到的却是一个xml文件：<br /><br /><img src="http://www.blogjava.net/images/blogjava_net/killme2008/rest3.bmp" alt="rest3.bmp" border="0" height="186" width="339" /><br /><br />不仅如此，我们也可以通过其他语言编写客户端来调用http://localhost:3000/people/1这个url，慢着，这不正是web service远程调用吗？没错，REST风格的web service相比于wsdl、soap定义的web service简单了太多太多，也更加实用。我们来编写一个java类调用http://localhost:3000/people获得所有的人员列表：<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">package</span><span style="color: rgb(0, 0, 0);"> example;<br /><br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> java.io.BufferedReader;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> java.io.InputStreamReader;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> java.io.OutputStreamWriter;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> java.net.HttpURLConnection;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> java.net.URL;<br /></span><span style="color: rgb(0, 0, 255);">import</span><span style="color: rgb(0, 0, 0);"> java.net.URLConnection;<br /><br /></span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> RESTDemo {<br /><br />    </span><span style="color: rgb(0, 128, 0);">/**</span><span style="color: rgb(0, 128, 0);"><br />     * </span><span style="color: rgb(128, 128, 128);">@param</span><span style="color: rgb(0, 128, 0);"> args<br />     </span><span style="color: rgb(0, 128, 0);">*/</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">public</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> main(String[] args) {<br />        RESTDemo restDemo </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> RESTDemo();<br />            restDemo.get();<br />        <br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> get() {<br /><br />        </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br />            URL url </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> URL(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">http://localhost:3000/people</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />            URLConnection urlConnection </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> url.openConnection();<br />            urlConnection.setRequestProperty(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">accept</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">text/xml</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />            BufferedReader in </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> BufferedReader(</span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> InputStreamReader(<br />                    urlConnection.getInputStream()));<br />            String str;<br /><br />            </span><span style="color: rgb(0, 0, 255);">while</span><span style="color: rgb(0, 0, 0);"> ((str </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> in.readLine()) </span><span style="color: rgb(0, 0, 0);">!=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">null</span><span style="color: rgb(0, 0, 0);">) {<br />                System.out.println(str);<br />            }<br /><br />            in.close();<br />        } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (Exception e) {<br />            System.out.println(e);<br />        }<br />    }<br />}</span></div><br />我们没有什么服务端接口class，我们也不用生成什么stub，我们调用的最常见最常见的http协议，发送的是默认的GET请求，rails自动将该请求转发给show action。注意，我们这里把<span style="color: rgb(0, 0, 0);">accept设置为text/xml，show方法根据此格式返回一个xml文档，下面是输出：<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">&lt;?</span><span style="color: rgb(255, 0, 255);">xml version="1.0" encoding="UTF-8"</span><span style="color: rgb(0, 0, 255);">?&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">people</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />  </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">person</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">email</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">killme2008@gmail.com</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">email</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">first-name</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">dennis</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">first-name</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">id </span><span style="color: rgb(255, 0, 0);">type</span><span style="color: rgb(0, 0, 255);">="integer"</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">1</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">id</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">last-name</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">zane</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">last-name</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />    </span><span style="color: rgb(0, 0, 255);">&lt;</span><span style="color: rgb(128, 0, 0);">phone</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);">1355XXXXXXX</span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">phone</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br />  </span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">person</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">&lt;/</span><span style="color: rgb(128, 0, 0);">people</span><span style="color: rgb(0, 0, 255);">&gt;</span><span style="color: rgb(0, 0, 0);"><br /></span></div><br />如果仅仅是GET请求是不够的，我们说过，把远程调用抽象成对远程资源的CRUD操作，那么如何create、delete和update远程资源呢？同样很简单，比如我们通过C#远程调用，创建一个新person，还记的我说过吗？/people可以是POST请求，他将调用PeopleController的create方法：<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System;<br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System.Net;<br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System.IO;<br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> System.Text;<br /></span><span style="color: rgb(0, 0, 255);">namespace</span><span style="color: rgb(0, 0, 0);"> demo<br />{<br />    </span><span style="color: rgb(0, 0, 255);">class</span><span style="color: rgb(0, 0, 0);"> RESTDemo<br />    {<br />        </span><span style="color: rgb(0, 0, 255);">static</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> Main(</span><span style="color: rgb(0, 0, 255);">string</span><span style="color: rgb(0, 0, 0);">[] args)<br />        {<br />            </span><span style="color: rgb(0, 0, 255);">string</span><span style="color: rgb(0, 0, 0);"> xmlText </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;person&gt; </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;first-name&gt;jordan&lt;/first-name&gt;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br />                    </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;last-name&gt;jordan&lt;/last-name&gt;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br />                    </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;email&gt;maggie@tate.com&lt;/email&gt;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br />                    </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;phone&gt;010-XXXXXXXX&lt;/phone&gt;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;/person&gt;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br />            Uri address </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> Uri(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">http://localhost:3000/people</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);  <br />   <br />            </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 创建web请求</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">            HttpWebRequest request </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> WebRequest.Create(address) </span><span style="color: rgb(0, 0, 255);">as</span><span style="color: rgb(0, 0, 0);"> HttpWebRequest;  <br />   <br />            </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);"> 设置请求类型为POST，调用create action</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">            request.Method </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">POST</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;  <br />            request.ContentType </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">application/xml</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br /><br />            </span><span style="color: rgb(0, 0, 255);">byte</span><span style="color: rgb(0, 0, 0);">[] xmlBytes </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Encoding.ASCII.GetBytes(xmlText);<br /><br />            </span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> (Stream reqStream </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> request.GetRequestStream())<br />            {<br />                reqStream.Write(xmlBytes, </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">, xmlBytes.Length);<br />            }<br />            </span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> (WebResponse wr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> request.GetResponse())<br />            {<br />                wr.<br />                </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">打印返回的http头</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">                Console.WriteLine(wr.Headers.ToString());<br />               <br />            }              <br />           <br /><br />        }<br />    }<br />}<br /></span></div><br />执行此程序，刷新http://localhost:3000/people，可以看到新建了一个人员如下<br /><br /><img src="http://www.blogjava.net/images/blogjava_net/killme2008/rest4.bmp" alt="rest4.bmp" border="0" height="156" width="558" /><br /></span><br />好极了，GET和POST都有了，那么PUT对应的更新和DELETE对应的删除又该怎么做呢，唯一的区别就是设置请求类型不同而已，java调用如下：<br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">    </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> put() {<br />        </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br />            String xmlText </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;person&gt; </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;first-name&gt;test&lt;/first-name&gt;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br />                    </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;last-name&gt;test&lt;/last-name&gt;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br />                    </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;email&gt;maggie@tate.com&lt;/email&gt;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"><br />                    </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;phone&gt;010-XXXXXXXX&lt;/phone&gt;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">&lt;/person&gt;</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br /><br />            URL url </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> URL(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">http://localhost:3000/people/1</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />            HttpURLConnection conn </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (HttpURLConnection) url.openConnection();<br />            conn.setDoOutput(</span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">);<br />            //设置请求为PUT<br />            conn.setRequestMethod(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">PUT</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />            conn.setRequestProperty(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Content-Type</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">text/xml</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />            OutputStreamWriter wr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> OutputStreamWriter(conn<br />                    .getOutputStream());<br />            wr.write(xmlText);<br />            wr.flush();<br />            wr.close();<br />        } </span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (Exception e) {<br />            System.out.println(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Error</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> e);<br />        }<br />    }<br /><br />    </span><span style="color: rgb(0, 0, 255);">void</span><span style="color: rgb(0, 0, 0);"> delete() {<br />        </span><span style="color: rgb(0, 0, 255);">try</span><span style="color: rgb(0, 0, 0);"> {<br />            URL url </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">new</span><span style="color: rgb(0, 0, 0);"> URL(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">http://localhost:3000/people/2</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />            HttpURLConnection conn </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (HttpURLConnection) url.openConnection();<br />            conn.setDoOutput(</span><span style="color: rgb(0, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">);<br />            //设置请求为DELETE<br />            conn.setRequestMethod(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">DELETE</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />            conn.setRequestProperty(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Content-Type</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">text/xml</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />            </span><span style="color: rgb(0, 0, 255);">if</span><span style="color: rgb(0, 0, 0);">(conn.getResponseCode()</span><span style="color: rgb(0, 0, 0);">==</span><span style="color: rgb(0, 0, 0);">200</span><span style="color: rgb(0, 0, 0);">)<br />                System.out.println(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">删除成功！</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br />        }</span><span style="color: rgb(0, 0, 255);">catch</span><span style="color: rgb(0, 0, 0);"> (Exception e) {<br />            System.out.println(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">Error</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> e);<br />        }<br />    }</span></div><br />这里的put方法将第一个人员的名字改了，而delete方法干脆将刚才C#添加的人员删除掉。异构系统的远程调用变的如此简单很轻松，把什么EJB、CORBA、SOAP统统忘掉吧。想象这样的场景，所有的网站都提供REST风格的API，这个世界将是什么模样？<br /><br />    REST带来的不仅仅是web service的改变，对MVC架构同样具有很重要的意义，过去我们的复用通常在MODEL层，我们一直希望复用业务逻辑层，却没有想过是否能复用Controller甚至View呢？REST为我们提供了可能，比如以一个很经常被提到的例子来说，用户加入某个圈子这个操作跟圈子的管理员将用户加入圈子的操作是一样，但是操作成功后的跳转显示的页面也许不同，过去也许我们是通过写两个不同的Action来实现，而现在，同一个Action（加入圈子这个操作）只负责发送数据（XML格式的文档），而页面的展示将留给客户端去选择，从而复用了Controller，减少了Action和View层的代码量。进一步，请你想象，REST与AJAX的技术结合产生多么有趣的画面。<b>REST仅用于提供数据</b>，展现更多的交给了客户端。<br /><br />    本文仅仅是我接触REST这两天的学习总结，对于REST的应用才刚刚起步，需要更多的探讨和实践。其实java实现REST也是相当简单的，servlet本身就是很好的模型，恐怕没有多人注意到HttpServlet类中的doPut和doDelete方法，我们过去太强调GET和POST，反而忽视了PUT和DELETE可能带来的改变。java开源世界中已经有了REST风格的框架，比如<a href="https://cetia4.dev.java.net/">cetia4，</a>这是一个servlet-base的REST框架，值的关注。<br /><img src ="http://www.blogjava.net/killme2008/aggbug/105083.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/killme2008/" target="_blank">dennis</a> 2007-03-20 20:04 <a href="http://www.blogjava.net/killme2008/archive/2007/03/20/105083.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用 HttpWebRequest 向网站提交数据</title><link>http://www.blogjava.net/killme2008/archive/2007/03/20/105023.html</link><dc:creator>dennis</dc:creator><author>dennis</author><pubDate>Tue, 20 Mar 2007 08:32:00 GMT</pubDate><guid>http://www.blogjava.net/killme2008/archive/2007/03/20/105023.html</guid><wfw:comment>http://www.blogjava.net/killme2008/comments/105023.html</wfw:comment><comments>http://www.blogjava.net/killme2008/archive/2007/03/20/105023.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/killme2008/comments/commentRss/105023.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/killme2008/services/trackbacks/105023.html</trackback:ping><description><![CDATA[
		<div class="postTitle">
				<a id="viewpost1_TitleUrl" class="postTitle2" href="http://www.cnblogs.com/webman/archive/2006/11/17/564106.html">转自：http://www.cnblogs.com/webman/archive/2006/11/17/564106.html<br /></a>
		</div>
	HttpWebRequest 是 .net 基类库中的一个类，在命名空间 System.Net 下面，用来使用户通过 HTTP 协议和服务器交互。 <br /><br />HttpWebRequest 对 HTTP 协议进行了完整的封装，对 HTTP 协议中的 Header, Content, Cookie 都做了属性和方法的支持，很容易就能编写出一个模拟浏览器自动登录的程序。 <br /><br />程序使用 HTTP 协议和服务器交互主要是进行数据的提交，通常数据的提交是通过 GET 和 POST 两种方式来完成，下面对这两种方式进行一下说明： <br /><br />1. GET 
方式。 GET 方式通过在网络地址附加参数来完成数据的提交，比如在地址 http://www.google.com/webhp?hl=zh-
CN 中，前面部分 http://www.google.com/webhp 表示数据提交的网址，后面部分 hl=zh-CN 表示附加的参数，其中
 hl 表示一个键(key)， zh-CN 表示这个键对应的值(value)。程序代码如下： <br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">HttpWebRequest req </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (HttpWebRequest) HttpWebRequest.Create( </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">http://www.google.com/webhp?hl=zh-CN</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> );<br />req.Method </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">GET</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> (WebResponse wr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> req.GetResponse())<br />{<br />   </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">在这里对接收到的页面内容进行处理</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">} <br /></span></div><br />2. POST 方式。 POST 方式通过在页面内容中填写参数的方法来完成数据的提交，参数的格式和 GET 方式一样，是类似于 hl=zh-CN&amp;newwindow=1 这样的结构。程序代码如下： <br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);"><br /></span><span style="color: rgb(0, 0, 255);">string</span><span style="color: rgb(0, 0, 0);"> param </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">hl=zh-CN&amp;newwindow=1</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br /></span><span style="color: rgb(0, 0, 255);">byte</span><span style="color: rgb(0, 0, 0);">[] bs </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Encoding.ASCII.GetBytes(param);<br /><br />HttpWebRequest req </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> (HttpWebRequest) HttpWebRequest.Create( </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">http://www.google.com/intl/zh-CN/</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> );<br />req.Method </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">POST</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br />req.ContentType </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">application/x-www-form-urlencoded</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">;<br />req.ContentLength </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> bs.Length;<br /><br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> (Stream reqStream </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> req.GetRequestStream())<br />{<br />   reqStream.Write(bs, </span><span style="color: rgb(0, 0, 0);">0</span><span style="color: rgb(0, 0, 0);">, bs.Length);<br />}<br /></span><span style="color: rgb(0, 0, 255);">using</span><span style="color: rgb(0, 0, 0);"> (WebResponse wr </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> req.GetResponse())<br />{<br />   </span><span style="color: rgb(0, 128, 0);">//</span><span style="color: rgb(0, 128, 0);">在这里对接收到的页面内容进行处理</span><span style="color: rgb(0, 128, 0);"><br /></span><span style="color: rgb(0, 0, 0);">} </span></div><br /><br />在上面的代码中，我们访问了 www.google.com 的网址，分别以 GET 和 POST 方式提交了数据，并接收了返回的页面内容。然而，如果提交的参数中含有中文，那么这样的处理是不够的，需要对其进行编码，让对方网站能够识别。 <br /><br />3. 使用 GET 方式提交中文数据。 GET 方式通过在网络地址中附加参数来完成数据提交，对于中文的编码，常用的有 gb2312 和 utf8 两种，用 gb2312 方式编码访问的程序代码如下： <br /><br /><div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: rgb(0, 0, 0);">Encoding myEncoding </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> Encoding.GetEncoding(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">gb2312</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">);<br /></span><span style="color: rgb(0, 0, 255);">string</span><span style="color: rgb(0, 0, 0);"> address  </span><span style="color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">http://www.baidu.com/s?</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> HttpUtility.UrlEncode(</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">参数一</span><span style="color: rgb(0, 0, 0);">"</span><span style="color: rgb(0, 0, 0);">, myEncoding) </span><span style="color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);">