A. java解決邏輯問題-》「Zebra Puzzle」 http://en.wikipedia.org/wiki/Zebra_puzzle
本來以為是很簡單的,沒想到越寫越僵了...總之,我的思路就是不斷的嘗試,遇到發生矛盾的話就回溯,直到所有的條件都滿足,下面貼的代碼在main方法中調用ZebraPuzzle的方法創建題目中的條件,最後列印出推導出來的表格,有了表格就什麼信息都有了。當然可能還有(幾乎是肯定有)很多漏洞,因為一個測試例子是不足以檢測所有邏輯的。。。另外這里也沒有包括糾錯的邏輯,比如如果題目本身是矛盾的話,我就不知道會發生什麼了。。。
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class Test {
public static void main(String[] args) {
String[] attributeName =
{ "Color", "Nationality", "Drink", "Cigarette", "Pet" };
ZebraPuzzle puzzle = new ZebraPuzzle(5, attributeName);
puzzle.bindCondition("Nationality", "ENG", "Color", "Red");
puzzle.bindCondition("Nationality", "ESP", "Pet", "Dog");
puzzle.bindCondition("Drink", "Coffee", "Color", "Green");
puzzle.bindCondition("Nationality", "UKR", "Drink", "Tea");
puzzle.bindNeighbour("Color", "Ivory", "Color", "Green", true);
puzzle.bindCondition("Cigarette", "OldGold", "Pet", "Snail");
puzzle.bindCondition("Cigarette", "Kool", "Color", "Yellow");
puzzle.bindOrdinal("Drink", "Milk", 3);
puzzle.bindOrdinal("Nationality", "NOW", 1);
puzzle.bindNeighbour("Cigarette", "Chester", "Pet", "Fox", false);
puzzle.bindNeighbour("Cigarette", "Kool", "Pet", "Horse", false);
puzzle.bindCondition("Cigarette", "Lucky", "Drink", "Juice");
puzzle.bindCondition("Nationality", "JPN", "Cigarette", "Parliament");
puzzle.bindNeighbour("Nationality", "NOW", "Color", "Blue", false);
boolean result = puzzle.solve();
System.out.println(result);
puzzle.printTable();
}
}
class ZebraPuzzle {
private List<Fact> conditions;
private String[] attributes;
private Unit[] units;
public ZebraPuzzle(int n, String[] attrs) {
attributes = attrs;
conditions = new ArrayList<Fact>();
units = new Unit[n];
for (int i = 0; i < n; ++i) {
units[i] = new Unit(i+1, attributes);
}
}
public void bindCondition(String type1, String attr1, String type2, String attr2) {
conditions.add(new BinderFact(type1, attr1, type2, attr2));
}
public void bindNeighbour(String type1, String attr1, String type2,
String attr2, boolean sideSensitive) {
if (sideSensitive) {
conditions.add(new SideSensitiveNeighbourFact(type1, attr1, type2, attr2));
} else {
conditions.add(new NeighbourFact(type1, attr1, type2, attr2));
}
}
public void bindOrdinal(String type, String attr, int ordinal) {
conditions.add(new OrdinalFact(type, attr, ordinal));
}
public boolean solve() {
applyOrdinalFact();
applyDeterministicFactor();
return solve(0);
}
private boolean solve(int depth) {
if (depth == conditions.size()) {
return true;
}
Fact fact = conditions.get(depth);
List<PossibleFact> possibles = fact.getPossibleFacts(units);
if (possibles.size() == 0) {
return false;
}
for (PossibleFact pf : possibles) {
pf.apply(units);
if (solve(depth + 1)) {
return true;
}
pf.cancel(units);
}
return false;
}
private void directApply(OrdinalFact fact) {
units[fact.ordinal-1].setOrdinalFact(fact);
}
private void applyOrdinalFact() {
Iterator<Fact> iter = conditions.iterator();
while (iter.hasNext()) {
Fact fact = iter.next();
if (fact instanceof OrdinalFact) {
directApply((OrdinalFact) fact);
iter.remove();
}
}
}
private void applyDeterministicFactor() {
boolean modified;
while (!conditions.isEmpty()) {
modified = false;
Iterator<Fact> iter = conditions.iterator();
while (iter.hasNext()) {
Fact fact = iter.next();
if (fact.tryApply(units)) {
iter.remove();
modified = true;
}
}
if (!modified) {
break;
}
}
}
public void printTable() {
System.out.print("\t\t");
for (String attribute : attributes) {
System.out.printf("%s\t\t", attribute);
}
System.out.print("\n");
for (Unit unit : units) {
System.out.printf("%d\t\t", unit.ordinal);
for (String attribute : attributes) {
System.out.printf("%s\t\t", unit.getAttribute(attribute));
}
System.out.print("\n");
}
System.out.println();
}
}
enum AttributeState { UNKNOWN, DIFFERENT, SELF }
class Unit {
Unit(int ordinal, String[] attributes) {
this.ordinal = ordinal;
map = new HashMap<String, String>();
for (String attr : attributes) {
map.put(attr, Fact.UNKNOWN);
}
}
void setOrdinalFact(OrdinalFact fact) {
map.put(fact.type, fact.attribute);
}
void setAttribute(String type, String attribute) {
map.put(type, attribute);
}
boolean containsAttribute(String type, String attribute) {
return attribute.equals(map.get(type));
}
boolean containsDifferentOne(String type, String attribute) {
String s = map.get(type);
return s != Fact.UNKNOWN && !s.equals(attribute);
}
AttributeState consultAttribute(String type, String attribute) {
String s = map.get(type);
if (s == Fact.UNKNOWN) {
return AttributeState.UNKNOWN;
}
if (s.equals(attribute)) {
return AttributeState.SELF;
}
return AttributeState.DIFFERENT;
}
Unit getRightUnit(Unit[] units) {
if (ordinal == units.length) {
return null;
}
return units[ordinal];
}
String getAttribute(String attributeName) {
return map.get(attributeName);
}
Map<String, String> map;
int ordinal;
}
interface Fact {
static final String UNKNOWN = "Unknown";
public List<PossibleFact> getPossibleFacts(Unit[] units);
public boolean tryApply(Unit[] units);
}
interface PossibleFact {
public void apply(Unit[] units);
public void cancel(Unit[] units);
}
abstract class AbstractFact implements Fact {
public boolean tryApply(Unit[] units) {
return false;
}
protected Unit findOwner(Unit[] units, String type, String attribute) {
for (Unit unit : units) {
if (unit.containsAttribute(type, attribute)) {
return unit;
}
}
return null;
}
public List<PossibleFact> getPossibleFacts(Unit[] units) {
return Collections.emptyList();
}
}
class BinderFact extends AbstractFact {
String type1, attribute1;
String type2, attribute2;
BinderFact(String t1, String attr1, String t2, String attr2) {
type1 = t1;
attribute1 = attr1;
type2 = t2;
attribute2 = attr2;
}
public boolean tryApply(Unit[] units) {
Unit unit = super.findOwner(units, type1, attribute1);
if (unit != null) {
return tryApply(unit, type2, attribute2);
}
unit = super.findOwner(units, type2, attribute2);
if (unit != null) {
return tryApply(unit, type1, attribute1);
}
return false;
}
protected boolean tryApply(Unit unit, String type, String attribute) {
if (unit.containsDifferentOne(type, attribute)) {
throw new RuntimeException();
}
unit.setAttribute(type, attribute);
return true;
}
public List<PossibleFact> getPossibleFacts(Unit[] units) {
List<PossibleFact> list = new ArrayList<PossibleFact>();
for (Unit unit : units) {
AttributeState as1 = unit.consultAttribute(type1, attribute1), as2 = unit.consultAttribute(type2, attribute2);
if (as1 != AttributeState.DIFFERENT && as2 != AttributeState.DIFFERENT) {
list.add(new PossiblebBinderFact(unit.ordinal, this,
as1 == AttributeState.UNKNOWN,
as2 == AttributeState.UNKNOWN
));
}
}
return list;
}
private static class PossiblebBinderFact implements PossibleFact {
BinderFact fact;
boolean firstNew, secondNew;
int n;
PossiblebBinderFact(int n, BinderFact fact, boolean fn, boolean sn) {
this.fact = fact;
firstNew = fn;
secondNew = sn;
this.n = n;
}
public void apply(Unit[] units) {
if (firstNew) {
units[n-1].setAttribute(fact.type1, fact.attribute1);
}
if (secondNew) {
units[n-1].setAttribute(fact.type2, fact.attribute2);
}
}
public void cancel(Unit[] units) {
if (firstNew) {
units[n-1].setAttribute(fact.type1, Fact.UNKNOWN);
}
if (secondNew) {
units[n-1].setAttribute(fact.type2, Fact.UNKNOWN);
}
}
}
}
class NeighbourFact extends BinderFact {
NeighbourFact(String t1, String attr1, String t2, String attr2) {
super(t1, attr1, t2, attr2);
}
public boolean tryApply(Unit[] units) {
if (tryApply(units, type1, attribute1, type2, attribute2)) {
return true;
}
if (tryApply(units, type2, attribute2, type1, attribute1)) {
return true;
}
return false;
}
protected boolean tryApply(Unit[] units, String t1, String attr1,
String t2, String attr2) {
Unit unit = super.findOwner(units, t1, attr1);
if (unit == null) {
return false;
}
Unit right = unit.getRightUnit(units);
if (right == null) {
return false;
}
return super.tryApply(right, t2, attr2);
}
public List<PossibleFact> getPossibleFacts(Unit[] units) {
List<PossibleFact> list = new ArrayList<PossibleFact>();
getPossibleFacts(units, list, type1, attribute1, type2, attribute2);
getPossibleFacts(units, list, type2, attribute2, type1, attribute1);
return list;
}
protected void getPossibleFacts(Unit[] units, List<PossibleFact> list,
String t1, String attr1, String t2, String attr2) {
for (int i = 0; i < units.length - 1; ++i) {
Unit unit1 = units[i], unit2 = units[i + 1];
AttributeState as1 = unit1.consultAttribute(t1, attr1), as2 = unit2.consultAttribute(t2, attr2);
if (as1 != AttributeState.DIFFERENT && as2 != AttributeState.DIFFERENT) {
list.add(new PossibleNeighbourFact(t1, attr1, t2, attr2,
i, i+1, as1 == AttributeState.UNKNOWN,
as2 == AttributeState.UNKNOWN
));
}
}
}
private static class PossibleNeighbourFact implements PossibleFact {
String type1, attribute1, type2, attribute2;
boolean firstNew, secondNew;
int n1, n2;
PossibleNeighbourFact(String t1, String a1, String t2, String a2,
int n1, int n2, boolean fn, boolean sn) {
type1 = t1;
attribute1 = a1;
type2 = t2;
attribute2 = a2;
firstNew = fn;
secondNew = sn;
this.n1 = n1;
this.n2 = n2;
}
public void apply(Unit[] units) {
if (firstNew) {
units[n1].setAttribute(type1, attribute1);
}
if (secondNew) {
units[n2].setAttribute(type2, attribute2);
}
}
public void cancel(Unit[] units) {
if (firstNew) {
units[n1].setAttribute(type1, Fact.UNKNOWN);
}
if (secondNew) {
units[n2].setAttribute(type2, Fact.UNKNOWN);
}
}
}
}
class SideSensitiveNeighbourFact extends NeighbourFact {
SideSensitiveNeighbourFact(String t1, String attr1, String t2, String attr2) {
super(t1, attr1, t2, attr2);
}
public boolean tryApply(Unit[] units) {
return super.tryApply(units, type1, attribute1, type2, attribute2);
}
public List<PossibleFact> getPossibleFacts(Unit[] units) {
List<PossibleFact> list = new ArrayList<PossibleFact>();
getPossibleFacts(units, list, type1, attribute1, type2, attribute2);
return list;
}
}
class OrdinalFact extends AbstractFact {
String type, attribute;
int ordinal;
OrdinalFact(String t, String attr, int ord) {
type = t;
attribute = attr;
ordinal = ord;
}
}
B. 什麼是JAVA
Java手機軟體平台採用的基本Java平台是CLDC (Connected Limited Device Configuration)和MIDP (Mobile Information Device Profile),是J2ME (Java 2 Micro Edition)的一部分,在中國一般稱為「無線Java」技術。此前,有人把它叫做「K-Java」;其實,K-Java的叫法只是Sun公司在開發 KVM Java虛擬機時的項目代號,在該技術被正式命名為KVM後,就不再用K-Java了。
Java技術的開放性、安全性和龐大的社會已有資源,以及其跨平台性,即「編寫一次,到處運行」的特點,使Java技術成為智能手機軟體平台的事實標准。
Java,是一種可以編寫跨平台應用軟體的面向對象的程序設計語言,由升陽(太陽微電子,Sun Microsystems)公司的James Gosling等人於1990年代初開發
參考資料:zh.wikipedia.org/wiki/Java
Java好象隨處可見 - 甚至在TV中。盡管如此,說清楚Java是什
么和它能做什麼卻不那麼容易。剛開始接觸Java的人通常有三
個問題:
什麼是Java?
Java能做什麼?
Java怎樣改變我的生活?
讓我們先回答第一個問題:什麼是Java?
Java既是一種編程語言,又是一個平台。
Java程序語言
Java是具有以下特徵的高級程序語言:
* 簡單
* 面向對象
* 可分布
* 可解釋
* 強壯
* 安全性
* 結構化
* 輕便
* 功能強大
* 多線程
* 動態
Java既可以被編譯,也可以被解釋。通過編譯器,可以把Java
程序翻譯成一種中間代碼 - 稱為位元組碼 - 可以被Java解釋器
解釋的獨立於平台的代碼。通過解釋器,每條Java位元組指令被
分析,然後在計算機上運行。只需編譯一次,程序運行時解釋
執行。下圖說明了它是如何工作的:
1flow.gif (3652 bytes)
可以把Java位元組碼看作運行在Java虛擬機(Java VM)上的機器
代碼指令。每中Java解釋器,不管是Java開發工具還是可以運
行Java小應用程序的Web瀏覽器,都是一種Java VM的實例。Java
VM也可以由硬體實現。
Java位元組碼使「寫一次,到處運行」成為可能。可以在任何有
Java編譯器的平台上把Java程序編譯成位元組碼。這個位元組碼可以
運行在任何Java VM上。例如,同一個Java程序可以運行在Windows
NT、Solaris和Macintosh上。
2comp.gif (6076 bytes)
Java平台
平台是程序運行的硬體或軟體環境。Java平台與大多數其它平台
不同之處在於它是運行於其它基於硬體平台的純軟體平台。大
多數其它平台是硬體和操作系統的結合。
Java平台由兩部分組成:
* Java虛擬機(Java VM)
* Java應用程序界面(Java API)
我們已經介紹了Java VM,它是Java平台的基礎,可以移植到各
種基於硬體的平台上。
Java API是軟體組件的集合,它們提供了很多有用的功能,如圖
形用戶界面(GUI)。Java API被分組為相關組件的庫(包)。
下圖描述了一個運行在Java平台上的Java程序,如應用程
序(application)或小應用程序(applet)。如圖中顯示的,Java
API和VM把Java程序從硬體依賴中分離出來。
3play.gif (1479 bytes)
作為一種獨立於平台的環境,Java比本地代碼慢一些。然而,聰
明的編譯器、很好地調制過的解釋器和即時位元組碼編譯器可以
在不犧牲可移植性的條件下使Java的表現接近本地代碼。
C. java 開發的wiki開源項目哪個比較好
https://hackpad.com/
https://www.oschina.net/p/xwiki
這兩個你可以參考下。
D. java 正則表達提取字元串";/w ;/w INFORMATION EXTRACTION/KW ;/w ;/w WIKI系統/KW"中的子串。
Java正則表達式:(?<=^|/KW)([\s\S]+?)/KW
完整的Java程序如下:(你字元串中的;/w我理解為空格或者tab字元,我用trim()函數去掉它)
importjava.util.regex.Matcher;
importjava.util.regex.Pattern;
publicclassA{
publicstaticvoidmain(String[]args){
Strings="INFORMATIONEXTRACTION/KWWIKI系統/KW";
Stringregex="(?<=^|/KW)([\s\S]+?)/KW";
Patternp=Pattern.compile(regex);
Matcherm=p.matcher(s);
while(m.find()){
System.out.println(m.group(1).trim());
}
}
}
運行結果:
INFORMATION EXTRACTION
WIKI系統
E. [關於xwiki]如何使用java實現向xwiki中去import一個xar。麻煩帶個例子,謝謝。
xwiki是一個開源網路系統,網上的二次開發介紹挺少的,這里會根據我開發中的具體問題進行總結。由於我是邊開發邊寫本文,最開始我也會很多都不清楚,請大家多指教。
目前xwiki的版本是5.2.1,我本地測試的版本是4.4.1 可能會有一些差異。
需要環境:tomcat伺服器、mysql資料庫,jdk,
1、下載xwiki
地址:http://enterprise.xwiki.org/xwiki/bin/view/Main/Download
其中包含了安裝包和源代碼包。(打開源代碼你會發現是一堆maven項目,可能會修改的代碼主要在xwiki-platform-master項目中。基本我們都是不需要修改java代碼的,不過這個項目下面是很多你能接觸到的,比如說搜索)
你最需要下載的包是war file。如下圖:
下載的文件裡面應該有一個xar結尾的文件,這個是xwiki的模板,如果沒有,請尋找對應的版本下載一個。
下載地址在改頁面能夠找到。
2、tomcat下安裝xwiki,並配置相關環境
前期准備:tomcat伺服器,和mysql資料庫。(這個安裝就不用介紹了,我也是做測試使用,tomcat是使用版本6)
將xwiki的war文件放在tomcat目錄下的webapps文件夾下,然後啟動tomcat。(雙擊tomcat目錄下bin文件夾中的startup.bat就好了,linux下是startup.sh)
此時xwiki項目會解壓縮,並且在xwiki下部署一個項目。你會發現tomcat會報錯,先不用管它。
3、進行參數配置
將mysql的驅動jar文件放到tomcat目錄下的lib文件夾下面(也可以放到對應項目下面的lib文件夾)。
將xwiki.cfg文件下的xwiki.superadminpassword=system這個一行前面的注釋去掉,這樣可以你就可以使用帳號superadmin/system登陸了,這個是管理員許可權。
建議將hsqldb資料庫部分注釋掉。(我就不截圖啦)
放開mysql連接部分的注釋,並且配置對應的值,注意,將mysql的驅動名編碼格式選擇正確(使用utf-8編碼格式),配置正確的用戶名和密碼。
在對應的資料庫中建立一個名為xwiki的資料庫,注意使用編碼格式是utf-8(與你上面的配置相對應,如果你修改的jar當中寫死了一個連接,你還要與這個連接資料庫名稱一致)。
修改mysql的配置文件my.ini,在[mysqld]這一樣下面增加一行
max_allowed_packet=32M(因為mysql默認包大小最多是1兆,不修改這個參數的話你今後導入模板包的時候會報錯)。
重新啟動tomcat(保證mysql是開著的哈)。這時候xwiki會自動在你剛才建立的xwiki資料庫中自動建立表格,並且導入部分數據。其中第一個表格,記錄了url響應和類的對應關系哦,有興趣的大神研究一下吧。
4、調試配置xwiki
此時在本地輸入localhost/xwiki(如果你tomcat配置不是默認的80埠,請加上你的tomcat伺服器的對應埠號,xwiki是我的項目名稱,如果你的項目名稱,也就是文件夾名字不是這個,請修改為對應的名稱)就能進入xwiki的頁面了。這個時候你看不到任何文檔,也沒有模板。
使用上面的帳號superadmin/system進行登錄,按照下圖進行,找到你下載的xwiki的初始模板.war文件,進行文件導入。
點擊你上傳的模板,在頁面的右邊會出現該模板的所以文件。將滾動條移動到最下方會發現有個導入按鈕(import)。點擊這個按鈕導入模板。今後你可能會根據開發需要還要導入很多其他模板,請按照這個過程進行導入。
設置xwiki的語言為中文,en代表因為,zh代表中文(因為不同版本的翻譯可能不一樣,而且開發文檔全部是英文的,可以的話就是用英文吧)
5、簡單使用
好了,現在xwiki已經搭建起來了,目前可以基於這個進行開發了。
xwiki的基本模式是先建空間,空間下面可以建立頁面(不能再建立空間了),頁面下面可以建立子頁面。頁面和子頁面的關系在每個頁面information下面能夠看到。
如果要進行xwiki的二次開發,那麼您需要准備以下知識。
velocity(重要,據說阿里也推崇這個)和groovy,如果需要整體運行java代碼的話,您還需要maven的知識。因為你開發xwiki的宏、對象和皮膚都需要可能會使用到這些知識,這些對於大神們肯定都不是問題。
F. 請問在win環境中怎麼安裝confluence-3.0-std的Java的wiki程序。
打開CRACK文件夾下的KEYGEN.exe
這時候會彈出一個方框.然後你就按照邏輯進行下一步.讓他生成一個序列號.然後你再打開安裝文件,會讓你輸入安裝序列號.你再把剛才生成的給填進去就成了.希望我的話能對你有所幫助
G. pmwiki 有沒有java版本
安裝步驟:1、將yalmip放到你的MATLAB的toolbox文件夾下;2、將yalmip文件目錄添加到MATLAB的path里(方法:matlab主界面:file->setpath)可直接選Addwithsubfolders注意:要將下面每一個文件目錄都添到matlab的path中/yalmip/yalmip/extras/yalmip/demos/yalmip/solvers/yalmip/moles/yalmip/moles/parametric/yalmip/moles/moment/yalmip/moles/global/yalmip/moles/robust/yalmip/moles/sos/yalmip/operators3、重啟matlab檢驗yalmip工具箱是否添成功。鍵入「whichsdpvar」。就可以了。
H. 推薦一款用 java 開發的,好用的wiki~謝謝
如果你是要做網站開發的話就用
MyEclipse
,如果是做桌面應用程序的話就用
Sun公司的
NetBeans
I. java的monitor機制中,為什麼阻塞隊列用list等待隊列用set
java阻塞隊列應用於生產者消費者模式、消息傳遞、並行任務執行和相關並發設計的大多數常見使用上下文。
BlockingQueue在Queue介面基礎上提供了額外的兩種類型的操作,分別是獲取元素時等待隊列變為非空和添加元素時等待空間變為可用。
BlockingQueue新增操作的四種形式:
3.2.1.3 HashMap類
對Map類的另外一個實現是HashMap。HashMap使用Hash表數據結構。HashMap假定哈希函數能夠將元素適當的分布在各桶之間,提供一種接近O(1)的查詢和更新操作。但是如果需要對集合進行迭代,則與HashMap的容量和桶的大小有關,因此HashMap的迭代效率不會很高(尤其是你為HashMap設置了較大的容量時)。
與HashMap性能有影響的兩個參數是,初始容量和載入因子。容量是哈希表中桶的數量,初始容量是哈希表在創建時的容量。載入因子是哈希表在容器容量被自動擴充之前,HashMap能夠達到多滿的一種程度。當hash表中的條目數超出了載入因子與當前容量的乘積時,Hash表需要進行rehash操作,此時Hash表將會擴充為以前兩倍的桶數,這個擴充過程需要進行完全的拷貝工作,效率並不高,因此應當盡量避免。合理的設置Hash表的初始容量和載入因子會提高Hash表的性能。HashMap自身不是線程安全的,可以通過Collections的synchronizedMap方法對HashMap進行包裝。
3.2.1.4 ConcurrentHashMap類
ConcurrentHashMap類實現了ConcurrentMap介面,並提供了與HashMap相同的規范和功能。實際上Hash表具有很好的局部可操作性,因為對Hash表的更新操作僅會影響到具體的某個桶(假設更新操作沒有引發rehash),對全局並沒有顯著影響。因此ConcurrentHashMap可以提供很好的並發處理能力。可以通過concurrencyLevel的設置,來控制並發工作線程的數目(默認為16),合理的設置這個值,有時很重要,如果這個值設置的過高,那麼很有可能浪費空間和時間,使用的值過低,又會導致線程的爭用,對數量估計的過高或過低往往會帶來明顯的性能影響。最好在創建ConcurrentHashMap時提供一個合理的初始容量,畢竟rehash操作具有較高的代價。
3.2.2 ConcurrentSkipListSet類
實際上Set和Map從結構來說是很像的,從底層的演算法原理分析,Set和Map應當屬於同源的結構。所以Java也提供了TreeSet和ConcurrentSkipListSet兩種SortedSet,分別適合於非多線程(或低並發多線程)和多線程程序使用。具體的演算法請參考前述的Map相關介紹,這里不在累述。
3.2.3 CopyOnWriteArrayList類
CopyOnWriteArrayList是ArrayList的一個線程安全的變體,其中對於所有的可變操作都是通過對底層數組進行一次新的復制來實現的。
由於可變操作需要對底層的數據進行一次完全拷貝,因此開銷一般較大,但是當遍歷操作遠遠多於可變操作時,此方法將會更有效,這是一種被稱為「快照」的模式,數組在迭代器生存期內不會發生更改,因此不會產生沖突。創建迭代器後,迭代器不會反映列表的添加、移除或者更改。不支持在迭代器上進行remove、set和add操作。CopyOnWriteArraySet與CopyOnWriteArrayList相似,只不過是Set類的一個變體。
3.2.3 Collections提供的線程安全的封裝
Collections中提供了synchronizedCollection、synchronizedList、synchronizedMap、synchronizedSet、synchronizedSortedMap、synchronizedSortedMap等方法可以完成多種集合的線程安全的包裝,如果在並發度不高的情況下,可以考慮使用這些包裝方法,不過由於Concurrent相關的類的出現,已經不這么提倡使用這些封裝了,這些方法有些人稱他們為過時的線程安全機制。
3.2.4簡單總結
提供線程安全的集合簡單概括分為三類,首先,對於並發性要求很高的需求可以選擇以Concurrent開頭的相應的集合類,這些類主要包括:ConcurrentHashMap、ConcurrentLinkedQueue、ConcurrentSkipListMap、ConcurrentSkipSet。其次對於可變操作次數遠遠小於遍歷的情況,可以使用CopyOnWriteArrayList和CopyOnWriteArraySet類。最後,對於並發規模比較小的並行需求可以選擇Collections類中的相應方法對已有集合進行封裝。
此外,本章還對一些集合類的底層實現進行簡單探討,對底層實現的了解有利於對何時使用何種方式作出正確判斷。希望大家能夠將涉及到原理(主要有循環隊列、堆、HashMap、紅黑樹、SkipList)進行仔細研究,這樣才能更深入了解Java為什麼這樣設計類庫,在什麼情況使用,應當如何使用。
J. 有沒有開源的java製作的類似「百科」或者「維基」的組件
JspWiki 是一套非常容易安裝的系統,使用到JSP與Servlet技術。
DevWiki是一個把頁面存儲在CVS中的Wiki引擎。
Chiki 點擊次數:944
基於Struts的Wiki系統。
SnipSnap 是一個基於java的wiki + WebLog
FITNesse是一個 基於FIT的測試環境,. 它內建Wiki伺服器,簡單易用。
Friki部署簡單,非常小隻有67k
XWiki是一個強大的Java開源的Wiki引擎。它支持一些受歡迎的特性如:
* 內容管理(瀏覽/編輯/預覽/保存),
* 支持附件,
* 版本控制,
* 全文本搜索,
* 許可權管理
* 使用Hibernate進行數據存儲,
* RSS輸出與顯示外部的RSS feeds,
* 多語言支持,
* 提供XML/RPC的API,
* WYSIWYG HTML編輯器,
* 導出為PDF
* Groovy腳本支持等等....。
ButorWiki這是一個基於java的Wiki,它是一個web應用程序,使用Butor Java 框架與struts MVC 框架。ButorWiki不需要資料庫,而是使用文件系統進行數據存儲。
Very Quick Wiki是一個JSPs與JavaServlets開發的WikiWiki。在Tomcat或其它容器上安裝與運行都很簡單。
UseModj這個Wiki引薦運用到Struts框架與Velocity模板。它具有一些新的特性:多語言支持,支持RSS 1.0(rdf),文件/圖片的上傳與下載,圖片大小調整,可以用多種語言命名文件/圖片
Platypus Wiki一個Semantic(語義的) Wiki Wiki Web.它提供一個簡單的使用基於W3C標准元數據(metadata)的用戶介面來創建Wiki頁面.Platypus Wiki使用RDF(Resource Description Framework:資源描述框架),RDF Schema和OWL(Web Ontology Language:Web實體語言)來創建實體(Ontology)與管理元數據.
CsaWiki是一個利用Java開發的wiki引擎。它具有以下特點:100%Java(J2EE沒有EJB),基於文件沒有資料庫,版本控制,PDF導出,簡單的Wiki sintax等。
Elsie是一個用Java開發的Wiki引擎。它支持大多數流行wiki所應具備的特性包括:簡單的wiki markup語法,內容管理(查看, 編輯,附件等...), 版本控制,訪問控制列表和用戶/組管理,可使用布局模板和CSS來控制外觀,一個用於創建公共文檔的文檔模板,支持I18N和多種語言,搜索等. Elsie實現一個基於IoC的wiki內核並提供一組定義清晰,獨立於servlet的wiki API 以便於使整個Wiki易於擴展和可定製。
Corendal Wiki是一個開源並已經被實際公司所使用的Wiki應用軟體。它的界面非常簡潔;不需要學習wiki語法, 通過使用WYSIWYG在線編輯器來代替;不需要用戶管理,它實時連到活動目錄(Active Directory)來重復使用用戶賬號和組,它應該是唯一一個與活動目錄組相集成的Wiki,本地賬號和組都可以用它來創建;所有的文章都具有一個層次結構,以使得內容易於管理;可以針對每一個頁面設置不同的訪問許可權或自由更新或鎖定或發布;用戶可以使用訂閱機制來獲得更新通知,更新可以是每天或每周或立即通知;可以自定義界面布局(使用Velocity模板和CSS實現) 。Corendal Wiki基於Tomcat和MySQL運行。
JAMWiki採用Java/JSP開發的Wiki引擎。它提供許多MediaWiki應具有大部份的功能。JAMWiki不需要資料庫支持,數據採用文件系統存儲(但)並且易於安裝。