import java.awt.*;
為若羌等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及若羌網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)、若羌網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
class JPanelEa1 extends JFrame implements MenuListener,ActionListener
{
JPanel mainp,p1,p2,p3,p4;
JTextField jt1;
JMenuItem mnuCopy;
JMenuItem mnuPaste;
JButton bM;
boolean isDouble = false;// 是否為實(shí)數(shù)
int opFlag = -1;
static double t1 = 0, t2 = 0, t3 = 0, result = 0;
static int opflag1 = -1, opflag2 = -1, flag = 0, resflag = 1;
int preOp, currentOp = 0;// 標(biāo)準(zhǔn)位
double op1 = 0, op2 = 0;// 操作數(shù)
double n3;
StringBuffer buf = new StringBuffer(20);
StringBuffer copyBoard = new StringBuffer(20);// 剪貼板
StringBuffer memory = new StringBuffer(20);// M系列
StringBuffer str = new StringBuffer();
public JPanelEa1()
{
p1=new JPanel();
p1.setLayout(new GridLayout(2,1,10,10));
JMenuBar mnuNotepad=new JMenuBar();
JMenu mnuEdit=new JMenu("編輯(E)");
mnuEdit.setMnemonic(KeyEvent.VK_E);
JMenu mnuCheck=new JMenu("查看(V)");
mnuCheck.setMnemonic(KeyEvent.VK_V);
JMenu mnuHelp=new JMenu("幫助(H)");
mnuCopy=new JMenuItem("復(fù)制(C)");
mnuPaste=new JMenuItem("粘貼(P)");
JMenuItem mnuVisit=new JMenuItem("查看幫助(V)");
JMenuItem mnuAbout=new JMenuItem("關(guān)于計(jì)算器(A)");
JSeparator sep=new JSeparator();
jt1=new JTextField("0.");
jt1.setEnabled(false);
jt1.setHorizontalAlignment(JTextField.RIGHT);
mnuEdit.addMenuListener(this);
mnuCheck.addMenuListener(this);
mnuHelp.addMenuListener(this);
mnuCopy.addActionListener(this);
mnuPaste.addActionListener(this);
mnuVisit.addActionListener(this);
mnuAbout.addActionListener(this);
mnuNotepad.add(mnuEdit);
mnuNotepad.add(mnuCheck);
mnuNotepad.add(mnuHelp);
mnuEdit.add(mnuCopy);
mnuEdit.add(mnuPaste);
mnuEdit.add(sep);
mnuHelp.add(mnuVisit);
mnuHelp.add(sep);
mnuHelp.add(mnuAbout);
p1.add(mnuNotepad);
p1.add(jt1);
p2=new JPanel();
p2.setLayout(new FlowLayout(FlowLayout.CENTER));
bM = new JButton(" ");
bM.setEnabled(false);
p2.add(bM);
Button b25=new Button("Backspace");
b25.addActionListener(this);
Button b26=new Button("CE");
b26.addActionListener(this);
Button b27=new Button("C");
b27.addActionListener(this);
p2.add(b25);
p2.add(b26);
p2.add(b27);
p3=new JPanel();
p3.setLayout(new GridLayout(4,6));
Button button1=new Button("MC");
button1.addActionListener(this);
Button button2=new Button("7");
button2.addActionListener(this);
Button button3=new Button("8");
button3.addActionListener(this);
Button button4=new Button("9");
button4.addActionListener(this);
Button button5=new Button("/");
button5.addActionListener(this);
Button button6=new Button("sqrt");
button6.addActionListener(this);
Button button7=new Button("MR");
button7.addActionListener(this);
Button button8=new Button("4");
button8.addActionListener(this);
Button button9=new Button("5");
button9.addActionListener(this);
Button button10=new Button("6");
button10.addActionListener(this);
Button button11=new Button("*");
button11.addActionListener(this);
Button button12=new Button("%");
button12.addActionListener(this);
Button button13=new Button("MS");
button13.addActionListener(this);
Button button14=new Button("1");
button14.addActionListener(this);
Button button15=new Button("2");
button15.addActionListener(this);
Button button16=new Button("3");
button16.addActionListener(this);
Button button17=new Button("-");
button17.addActionListener(this);
Button button18=new Button("1/x");
button18.addActionListener(this);
Button button19=new Button("M+");
button19.addActionListener(this);
Button button20=new Button("0");
button20.addActionListener(this);
Button button21=new Button("+/-");
button21.addActionListener(this);
Button button22=new Button(".");
button22.addActionListener(this);
Button button23=new Button("+");
button23.addActionListener(this);
Button button24=new Button("=");
button24.addActionListener(this);
p3.add(button1);p3.add(button2);
p3.add(button3);p3.add(button4);
p3.add(button5);p3.add(button6);
p3.add(button7);p3.add(button8);
p3.add(button9);p3.add(button10);
p3.add(button11);p3.add(button12);
p3.add(button13);p3.add(button14);
p3.add(button15);p3.add(button16);
p3.add(button17);p3.add(button18);
p3.add(button19);p3.add(button20);
p3.add(button21);p3.add(button22);
p3.add(button23);p3.add(button24);
setSize(250,150);
mainp=new JPanel();
mainp.setLayout(new GridLayout(3,1));
mainp.add(p1);
mainp.add(p2);
mainp.add(p3);
setContentPane(mainp);
setTitle("計(jì)算器");
setSize(300,300);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e)
{
String s= e.getActionCommand();
if (s.equals("復(fù)制(C)")) {
String temp = jt1.getText().trim();
copyBoard.replace(0, copyBoard.length(), temp);
mnuPaste.setEnabled(true);
} else if (s.equals("粘貼(p)")) {
jt1.setText(copyBoard.toString());
} else if (s.equals("CE")) {
// 如果是CE則清除文本框
jt1.setText("0.");
} else if (s.equals("Backspace")) {
if (!jt1.getText().trim().equals("0.")) {
// 如果文本框中有內(nèi)容
if (str.length() != 1 str.length() != 0) {
jt1.setText(str.delete(str.length() - 1, str.length())
.toString());
} else {
jt1.setText("0.");
str.setLength(0);
}
}
op2 = Double.parseDouble(jt1.getText().trim());
} else if (s.equals("C")) {
// 如果是C刪除當(dāng)前計(jì)算
jt1.setText("0.");
op1 = op2 = 0;
str.replace(0, str.length(), " ");
preOp = currentOp = 0;
} else if (s.equals("MC")) {
// 如果是MC則清除緩沖區(qū)
String temp = "";
memory.replace(0, memory.length(), temp);
bM.setText(" ");
} else if (s.equals("MR")) {
// 如果按鍵為MR則恢復(fù)緩沖區(qū)的數(shù)到文本框
jt1.setText(memory.toString());
} else if (s.equals("MS")) {
// 如果按鍵為MS則將文本框的數(shù)存入緩沖區(qū)
String s1 = jt1.getText().trim();
memory.replace(0, memory.length(), s1);
bM.setText("M");
} else if (s.equals("M+")) {
// 如果按鍵為MS則將文本框值與緩沖區(qū)的數(shù)相加但不顯示結(jié)果
String temp1 = jt1.getText().trim();
double dtemp = Double.parseDouble(temp1);
String temp2 = memory.toString();
dtemp += Double.parseDouble(temp2);
temp1 = String.valueOf(dtemp);
memory.replace(0, memory.length(), temp1);
} else if (s.equals("1/x")) {
// 如果按鍵為1/x則將文本框中的數(shù)據(jù)為它的倒數(shù)
String temp = jt1.getText().trim();
double dtemp = Double.parseDouble(temp);
jt1.setText("" + 1 / dtemp);
} else if (s.equals("sqrt")) {
// 如果按鍵為sqrt則將文本框中的內(nèi)容求平方根
String temp = jt1.getText().trim();
double dtemp = Double.parseDouble(temp);
jt1.setText("" + Math.sqrt(dtemp));
} else if (s.equals("+")) {
str.setLength(0);
if (currentOp == 0) {
preOp = currentOp = 1;
op2 = 0;
jt1.setText("" + op1);
} else {
currentOp = preOp;
preOp = 1;
switch (currentOp) {
case 1:
op1 += op2;
jt1.setText("" + op1);
break;
case 2:
op1 -= op2;
jt1.setText("" + op1);
break;
case 3:
op1 *= op2;
jt1.setText("" + op1);
break;
case 4:
op1 /= op2;
jt1.setText("" + op1);
break;
}
}
} else if (s.equals("-")) {
str.setLength(0);
if (currentOp == 0) {
preOp = currentOp = 2;// op1=op2;op2=0;
jt1.setText("" + op1);
} else {
currentOp = preOp;
preOp = 2;
switch (currentOp) {
case 1:
op1 = op1 + op2;
jt1.setText("" + op1);
break;
case 2:
op1 = op1 - op2;
jt1.setText("" + op1);
break;
case 3:
op1 = op1 * op2;
jt1.setText("" + op1);
break;
case 4:
op1 = op1 / op2;
jt1.setText("" + op1);
break;
}
}
} else if (s.equals("*"))// *
{
str.setLength(0);
if (currentOp == 0) {
preOp = currentOp = 3;// op1=op2;op2=1;
jt1.setText("" + op1);// op1=op2;
} else {
currentOp = preOp;
preOp = 3;
switch (currentOp) {
case 1:
op1 = op1 + op2;
jt1.setText("" + op1);
break;
case 2:
op1 = op1 - op2;
jt1.setText("" + op1);
break;
case 3:
op1 = op1 * op2;
jt1.setText("" + op1);
break;
case 4:
op1 = op1 / op2;
jt1.setText("" + op1);
break;
}
}
} else if (s.equals("/"))// /
{
str.setLength(0);
if (currentOp == 0) {
preOp = currentOp = 4;// op2=1;
jt1.setText("" + op1);// op1=op2;
} else {
currentOp = preOp;
preOp = 4;
switch (currentOp) {
case 1:
op1 = op1 + op2;
jt1.setText("" + op1);
break;
case 2:
op1 = op1 - op2;
jt1.setText("" + op1);
break;
case 3:
op1 = op1 * op2;
jt1.setText("" + op1);
break;
case 4:
op1 = op1 / op2;
jt1.setText("" + op1);
break;
}
}
} else if (s.equals("="))// =
{
if (currentOp == 0) {
str.setLength(0);
jt1.setText("" + op2);
} else {
str.setLength(0);
currentOp = preOp;
switch (currentOp) {
case 1:
op1 = op1 + op2;
jt1.setText("" + op1);
break;
case 2:
op1 = op1 - op2;
jt1.setText("" + op1);
break;
case 3:
op1 = op1 * op2;
jt1.setText("" + op1);
break;
case 4:
op1 = op1 / op2;
jt1.setText("" + op1);
break;
}
currentOp = 0;
op2 = 0;
}
} else if (s.equals(".")) {
isDouble = true;
if (jt1.getText().trim().indexOf('.') != -1)
;
else {
if (jt1.getText().trim().equals("0")) {
str.setLength(0);
jt1.setText((str.append("0" + s)).toString());
}
// else
// if(jt1.getText().trim().equals("")){}//如果初時(shí)顯示為空則不做任何操作
else {
jt1.setText((str.append(s)).toString());
}
}
} else if (s.equals("0"))// 如果選擇的是"0"這個(gè)數(shù)字鍵
{
if (jt1.getText().trim().equals("0.")) {
} else {
jt1.setText(str.append(s).toString());
op2 = Double.parseDouble(jt1.getText().trim());
}
} else {
jt1.setText(str.append(s).toString());
op2 = Double.parseDouble(jt1.getText().trim());
if (currentOp == 0)
op1 = op2;
}
}
public static void main(String args[])
{
JPanelEa1 g=new JPanelEa1();
}
@Override
public void menuSelected(MenuEvent e) {
// TODO Auto-generated method stub
}
@Override
public void menuDeselected(MenuEvent e) {
// TODO Auto-generated method stub
}
@Override
public void menuCanceled(MenuEvent e) {
// TODO Auto-generated method stub
}
}
這是一個(gè)java基礎(chǔ)題
雖然基礎(chǔ),但是我們練習(xí)的時(shí)候,可以加以拓展和優(yōu)化,熟悉for循環(huán) while循環(huán), 了解運(yùn)算符優(yōu)先級, ? 加強(qiáng)對業(yè)務(wù)邏輯的分析處理,強(qiáng)化寫代碼的能力。
首先代碼的寫法是多樣的
1.根據(jù)奇數(shù)定義 : ? 不能被2所整除的數(shù)是奇數(shù)
根據(jù)這個(gè)定義,我們可以寫一個(gè)最基礎(chǔ)的版本
public?class?Odd1?{
public?static?void?main(String[]?args)?{
for?(int?i?=?1;?i??1000;?i++)?{//1~1000之間?循環(huán)1000次
if(i%2!=0){??//不能被2整除的
System.out.println(i);//就是奇數(shù),打印出來
}
}
}
}
分析下,這個(gè)版本,我們發(fā)現(xiàn)這個(gè)版本性能可能比較低
因?yàn)橐h(huán)1000次,并且每次還要進(jìn)行一次求余運(yùn)算。所以性能低。
有沒有改進(jìn)的空間?
2. ? 我們繼續(xù)對奇數(shù)進(jìn)行了解(對業(yè)務(wù)進(jìn)行熟悉)。還有改進(jìn)的空間
然后發(fā)現(xiàn):?偶數(shù)可用2k表示,奇數(shù)可用2k+1表示,這里k是整數(shù)。
代碼修改如下
public?class?Odd2?{
public?static?void?main(String[]?args)?{
for?(int?k?=?0;?k??500;?k++)?{//循環(huán)減少為500次
System.out.println(k*2+1);//按照奇數(shù)公式進(jìn)行輸出
}
}
}
3. ?繼續(xù)優(yōu)化. ? java中乘法是性能消耗比較大的運(yùn)算, ?如果可以使用移位操作 , ?那么使用移位操作代替乘法
因?yàn)槭褂靡莆坏牟僮鲗?huì)更快和更有效
public?class?Odd3?{
public?static?void?main(String[]?args)?{
for?(int?k?=?0;?k??500;?k++)?{
System.out.println((k1)+1);//移位操的優(yōu)先級低于四則運(yùn)算,?所以用括號括起來優(yōu)先計(jì)算?,?左移1位.相當(dāng)于*2
}
}
}
4. ?查看奇數(shù)的特性 ?, 來探索其他寫法
奇數(shù)1、3、5、7、9、11、13、15、17、19、21、23、25、27、29、31、33.........
每個(gè)奇數(shù)的間隔是2, 第一個(gè)奇數(shù)是1
代碼如下
public?class?Odd4?{
public?static?void?main(String[]?args)?{
for?(int?i?=?1;?i??1000;?i+=2)?{//從1開始,每次自加2
System.out.println(i);
}
}
}
5. 除開for循環(huán), ?while循環(huán)也可以寫.
public?class?Odd5?{
public?static?void?main(String[]?args)?{
int?i?=?1;
while?(true)?{
if?(i?=?1000)?{
break;//跳出循環(huán)
}
System.out.println(i);
i?=?i?+?2;
}
}
}
6 ?再次修改,如果業(yè)務(wù)邏輯 從1~1000修改成其他數(shù)字了, 那么在循環(huán)體中修改不是特別合適
所以需要定義成2個(gè)變量. 來記錄開始的數(shù)字和結(jié)束的數(shù)字. ?并且如果輸出太多的數(shù)字, 不方便查看, ?那么需要美化下輸出的格式
public?class?Odd6?{
public?static?void?main(String[]?args)?{
int?start?=?1;?//開始的數(shù)
int?end?=?1000;?//結(jié)束的數(shù)
int?index?=0;//用于換行處理的計(jì)算
for?(int?n?=?start;?n??end;?n?+=?2)?{
index++;
System.out.print(n+"\t");//??\t表示制表符??,這樣數(shù)字看起來排列比較整齊
if(index%10==0){//每10個(gè)數(shù)字,換一行
System.out.println();
}
}
}
}
我從我的博客里把我的文章粘貼過來吧,對于單例模式模式應(yīng)該有比較清楚的解釋:
單例模式在我們?nèi)粘5捻?xiàng)目中十分常見,當(dāng)我們在項(xiàng)目中需要一個(gè)這樣的一個(gè)對象,這個(gè)對象在內(nèi)存中只能有一個(gè)實(shí)例,這時(shí)我們就需要用到單例。
一般說來,單例模式通常有以下幾種:
1.饑漢式單例
public class Singleton {
private Singleton(){};
private static Singleton instance = new Singleton();
public static Singleton getInstance(){
return instance;
}
}
這是最簡單的單例,這種單例最常見,也很可靠!它有個(gè)唯一的缺點(diǎn)就是無法完成延遲加載——即當(dāng)系統(tǒng)還沒有用到此單例時(shí),單例就會(huì)被加載到內(nèi)存中。
在這里我們可以做個(gè)這樣的測試:
將上述代碼修改為:
public class Singleton {
private Singleton(){
System.out.println("createSingleton");
};
private static Singleton instance = new Singleton();
public static Singleton getInstance(){
return instance;
}
public static void testSingleton(){
System.out.println("CreateString");
}
}
而我們在另外一個(gè)測試類中對它進(jìn)行測試(本例所有測試都通過Junit進(jìn)行測試)
public class TestSingleton {
@Test
public void test(){
Singleton.testSingleton();
}
}
輸出結(jié)果:
createSingleton
CreateString
我們可以注意到,在這個(gè)單例中,即使我們沒有使用單例類,它還是被創(chuàng)建出來了,這當(dāng)然是我們所不愿意看到的,所以也就有了以下一種單例。
2.懶漢式單例
public class Singleton1 {
private Singleton1(){
System.out.println("createSingleton");
}
private static Singleton1 instance = null;
public static synchronized Singleton1 getInstance(){
return instance==null?new Singleton1():instance;
}
public static void testSingleton(){
System.out.println("CreateString");
}
}
上面的單例獲取實(shí)例時(shí),是需要加上同步的,如果不加上同步,在多線程的環(huán)境中,當(dāng)線程1完成新建單例操作,而在完成賦值操作之前,線程2就可能判
斷instance為空,此時(shí),線程2也將啟動(dòng)新建單例的操作,那么多個(gè)就出現(xiàn)了多個(gè)實(shí)例被新建,也就違反了我們使用單例模式的初衷了。
我們在這里也通過一個(gè)測試類,對它進(jìn)行測試,最后面輸出是
CreateString
可以看出,在未使用到單例類時(shí),單例類并不會(huì)加載到內(nèi)存中,只有我們需要使用到他的時(shí)候,才會(huì)進(jìn)行實(shí)例化。
這種單例解決了單例的延遲加載,但是由于引入了同步的關(guān)鍵字,因此在多線程的環(huán)境下,所需的消耗的時(shí)間要遠(yuǎn)遠(yuǎn)大于第一種單例。我們可以通過一段測試代碼來說明這個(gè)問題。
public class TestSingleton {
@Test
public void test(){
long beginTime1 = System.currentTimeMillis();
for(int i=0;i100000;i++){
Singleton.getInstance();
}
System.out.println("單例1花費(fèi)時(shí)間:"+(System.currentTimeMillis()-beginTime1));
long beginTime2 = System.currentTimeMillis();
for(int i=0;i100000;i++){
Singleton1.getInstance();
}
System.out.println("單例2花費(fèi)時(shí)間:"+(System.currentTimeMillis()-beginTime2));
}
}
最后輸出的是:
單例1花費(fèi)時(shí)間:0
單例2花費(fèi)時(shí)間:10
可以看到,使用第一種單例耗時(shí)0ms,第二種單例耗時(shí)10ms,性能上存在明顯的差異。為了使用延遲加載的功能,而導(dǎo)致單例的性能上存在明顯差異,
是不是會(huì)得不償失呢?是否可以找到一種更好的解決的辦法呢?既可以解決延遲加載,又不至于性能損耗過多,所以,也就有了第三種單例:
3.內(nèi)部類托管單例
public class Singleton2 {
private Singleton2(){}
private static class SingletonHolder{
private static Singleton2 instance=new Singleton2();
}
private static Singleton2 getInstance(){
return SingletonHolder.instance;
}
}
在這個(gè)單例中,我們通過靜態(tài)內(nèi)部類來托管單例,當(dāng)這個(gè)單例被加載時(shí),不會(huì)初始化單例類,只有當(dāng)getInstance方法被調(diào)用的時(shí)候,才會(huì)去加載
SingletonHolder,從而才會(huì)去初始化instance。并且,單例的加載是在內(nèi)部類的加載的時(shí)候完成的,所以天生對線程友好,而且也不需要
synchnoized關(guān)鍵字,可以說是兼具了以上的兩個(gè)優(yōu)點(diǎn)。
4.總結(jié)
一般來說,上述的單例已經(jīng)基本可以保證在一個(gè)系統(tǒng)中只會(huì)存在一個(gè)實(shí)例了,但是,仍然可能會(huì)有其他的情況,導(dǎo)致系統(tǒng)生成多個(gè)單例,請看以下情況:
public class Singleton3 implements Serializable{
private Singleton3(){}
private static class SingletonHolder{
private static Singleton3 instance = new Singleton3();
}
public static Singleton3 getInstance(){
return SingletonHolder.instance;
}
}
通過一段代碼來測試:
@Test
public void test() throws Exception{
Singleton3 s1 = null;
Singleton3 s2 = Singleton3.getInstance();
//1.將實(shí)例串行話到文件
FileOutputStream fos = new FileOutputStream("singleton.txt");
ObjectOutputStream oos =new ObjectOutputStream(fos);
oos.writeObject(s2);
oos.flush();
oos.close();
//2.從文件中讀取出單例
FileInputStream fis = new FileInputStream("singleton.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
s1 = (Singleton3) ois.readObject();
if(s1==s2){
System.out.println("同一個(gè)實(shí)例");
}else{
System.out.println("不是同一個(gè)實(shí)例");
}
}
輸出:
不是同一個(gè)實(shí)例
可以看到當(dāng)我們把單例反序列化后,生成了多個(gè)不同的單例類,此時(shí),我們必須在原來的代碼中加入readResolve()函數(shù),來阻止它生成新的單例
public class Singleton3 implements Serializable{
private Singleton3(){}
private static class SingletonHolder{
private static Singleton3 instance = new Singleton3();
}
public static Singleton3 getInstance(){
return SingletonHolder.instance;
}
//阻止生成新的實(shí)例
public Object readResolve(){
return SingletonHolder.instance;
}
}
再次測試時(shí),就可以發(fā)現(xiàn)他們生成的是同一個(gè)實(shí)例了。
因?yàn)閥ear 是static 靜態(tài)類型,靜態(tài)變量無論你new 多少個(gè)對象,值是共用的,先S1.year=19;后你又S2.year=20, 所以 無論是 輸出S1.year還是S2.year都是20,你要是不S2.year=20 那么 S2.year 輸出的就是19了