1. 简单粗暴之界面
代码:
setTitle("计算器"); //设置窗体标题
setSize(266,340); //设定框体大小
Container c=getContentPane(); //获得容器对象
c.setLayout(null); //容器c设置为不采用任何布局管理器
JTextArea jt=new JTextArea(100,100); //创建文本域对象 jt
jt.setFont(new Font("Aria",Font.BOLD,32)); //设置字体
jt.setLineWrap(true); //自动换行
JScrollPane sp=new JScrollPane(jt); //滚动面板
jt.setCaretPosition(jt.getDocument().getLength()); //将滚动条自动拉到jt最底端,
sp.setBounds(0,0,250,100); //设置滚动面板位置大小
c.add(sp); //将sp添加到c
JPanel p=new JPanel(); //操作部分面板
p.setLayout(new GridLayout(5,4,0,0)); //采用网格布局管理器,分为5行4列
p.setBounds(0,100,250,200);
String[] num={"(",")","AC","/","7","8","9","*","4","5","6","-","1","2","3","+","0",".","DEL","="};
JButton[] jb=new JButton[20]; //操作按钮
for(int i=0;i<20;i++){
jb[i]=new JButton(num[i]);
p.add(jb[i]);
}
c.add(p);
//禁止文本域的enter换行
KeyStroke enter = KeyStroke.getKeyStroke("ENTER");
jt.getInputMap().put(enter, "none");
this.getRootPane().setDefaultButton(jb[19]);//回车触发默认按钮,也就是“=”
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
以上仅仅为界面显示的代码。注释那么多肯定能看懂了。
2. 简单粗暴之事件监听
代码:
for(int i=0;i<18;i++){
if(i!=2){
final int j=i;
jb[i].addActionListener(e-> jt.append(num[j]));
}
}
//事件监听,点击按钮AC,清空栈
//使用Java8 lambda表达式事件处理 哈哈哈更加简洁好看了
jb[2].addActionListener(e->{
jt.setText("");
operandStack.clear();
operatorStack.clear();
});
//点击按钮DEL,利用截取字符串,每次截取除最后一个字符实现这个功能
jb[18].addActionListener(e->{
try{
jt.setText(jt.getText().substring(0,jt.getText().length()-1));//截取字符串
}catch(Exception ignored) { }//忽略这个异常 IDEA就是好用!!!
});
//处理“=”的事件,
jb[19].addActionListener(e->{
try{
//double x= calculate(jt.getText()+"#");
jt.setText("");
// jt.append(String.valueOf(x)); //连接一个字符串到末尾
}catch(Exception ex){
if(ex.getMessage()==null)
jt.setText("ERROR!");
else
jt.setText(ex.getMessage());
}
});
//禁止文本域的enter换行
KeyStroke enter = KeyStroke.getKeyStroke("ENTER");
jt.getInputMap().put(enter, "none");
this.getRootPane().setDefaultButton(jb[19]);//回车触发默认按钮
这里主要需要注意的就是Java8新特性 Lambda表达式了,
举一个栗子:用lambda表达式写出更好的事件监听代码,如下所示:
// Java 8之前:
JButton show = new JButton("Show");
show.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Event handling without lambda expression is boring");
}
});
// Java 8方式:
show.addActionListener((e) -> {
System.out.println("Light, Camera, Action !! Lambda expressions Rocks");
});
是不是看起来变得简洁了。
3. 简单粗暴之算符优先算法
重点:算符优先算法。
上学期学数据结构用C语言写过,不过差不多都忘了,顺便又复习一下数据库结构了。
直接扔代码:
private void calculate(){
String b = operatorStack.pop(); //出栈
double c = operandStack.pop();
double d = operandStack.pop();
double e;
if (b.equals("+")) {
e = d + c;
operandStack.push(e); //入栈
}
if (b.equals("-")) {
e = d - c;
operandStack.push(e);
}
if (b.equals("*")) {
e = d * c;
operandStack.push(e);
}
if (b.equals("/")) {
if(c==0)
throw new ArithmeticException("DivideByZero!");//不可修改为Exception
// Exception的异常是必须处理的,是受控异常;而ArithmeticException 不是必须处理的 ,受控异常必须强制处理
e = d / c;
operandStack.push(e);
}
}
private Double calculate(String text){
//利用hashMap设置运算符间的优先关系
HashMap<String,Integer> precede=new HashMap<>();
precede.put("(",0);
precede.put(")",0);
precede.put("/",2);
precede.put("*",2);
precede.put("-",1);
precede.put("+",1);
precede.put("#",0);
operatorStack.push("#");
//算符优先算法
int flag=0;
for(int i=0;i<text.length();i++){
String a=String.valueOf(text.charAt(i));
if(!a.matches("[0-9.]")){
if(flag!=i)
operandStack.push(Double.parseDouble(text.substring(flag,i)));
flag=i+1;
while(!(a.equals("#")&&operatorStack.peek().equals("#"))){
if(precede.get(a)>precede.get(operatorStack.peek())||a.equals("(")){
operatorStack.push(a);
break;
}else {
if(a.equals(")")) {
while(!operatorStack.peek().equals("("))
calculate();
operatorStack.pop();
break;
}
calculate();
}
}
}
}
return(operandStack.pop());
}
本计算器主要代码部分。同C语言利用栈完成算符优先算法。
栈:stack()
|方法描述|
---|---|---
1|boolean empty() 测试堆栈是否为空。
2|Object peek( ) 查看堆栈顶部的对象,但不从堆栈中移除它。
3|Object pop( ) 移除堆栈顶部的对象,并作为此函数的值返回该对象。
4|Object push(Object element) 把项压入堆栈顶部。
5|int search(Object element) 返回对象在堆栈中的位置,以 1 为基数。
HashMap集合
采用键-值对的存储方式,长度可动态改变。
HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。
该类实现了Map接口,根据键的HashCode值存储数据,具有很快的访问速度,最多允许一条记录的键为null,不支持线程同步。
算符优先算法
网友评论