java初学者常见问题(2)

1.    Java中执行某个shell命令

Java提供了Runtime类来执行shell命令。由于这些是外部的命令,因此异常处理就显得异常重要。在下面的例子中,我们将通过一个简单的例子来演示一下。我们会在shell命令行中打开一个pdf文件。

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

publicclassShellCommandExec{

    
publicstaticvoid main(String[] args){
        
StringgnomeOpenCommand ="gnome-open//home//user//Documents//MyDoc.pdf";

        
try{
            
Runtime rt =Runtime.getRuntime();
            
Process processObj = rt.exec(gnomeOpenCommand);

            
InputStream stdin = processObj.getErrorStream();
            
InputStreamReader isr =newInputStreamReader(stdin);
            
BufferedReader br =newBufferedReader(isr);

            
String myoutput ="";

            
while((myoutput=br.readLine())!=null){
                myoutput 
= myoutput+"\n";
            
}
            
System.out.println(myoutput);
        
}
        
catch(Exception e){
            e
.printStackTrace();
        
}
    
}
}

1.    使用正则

正则表达式的结构摘录如下(来源: Oracle官网)

字符

x

字符x

\

反斜杠

\0n

8进制值为0n的字符(0<=n<=7)

\0nn

\0mnn

8进制值为0mnn的字符(0 <= m <= 3, 0<=n<=7)

\xhh

16进制值为0xhh的字符

\uhhhh

16进制值为0xhhhh的字符

\x{h…h}

16进制值为0xh…h的字符(Character.MINCODEPOINT <= 0xh…h <= Character.MAXCODEPOINT)

\t

制表符(‘\u0009′)

\n

换行符(‘\u000A’)

\r

回车(‘\u000D’)

\f

分页符(‘\u000C’)

\a

警告符(‘\u0007′)

\e

ESC(‘\u001B’)

\cx

ctrl+x

字符分类

[abc]

a, bc

[^abc]

abc以外的任意字符

[a-zA-Z]

az以及AZ

[a-d[m-p]]

ad或者mp[a-dm-p]则是取并集

[a-z&&[def]]

d,ef(交集)

[ad-z]

[a-z&&[^bc]]

az但不包括bc

[a-z&&[^m-p]]

az但不包括mp:也就是[a-lq-z]

预定义字符

.

任意字符,有可能包括换行符

\d

09的数字

\D

09以外的字符

\s

空格符[ \t\n\x0B\f\r]

\S

非空格符[^\s]

\w

字母[a-zA-Z_0-9]

\W

非字母[^\w]

边界匹配

^

行首

$

行末

\b

单词边界

\A

输入的起始位置

\G

前一个匹配的末尾

\Z

输入的结束位置,仅用于最后的结束符

\z

输入的结束位置

import java.util.regex.Matcher;
import java.util.regex.Pattern;

publicclassRegexMatches
{
    
privatestaticString pattern =  "^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
    
privatestaticPattern mypattern =Pattern.compile(pattern);
    
    
publicstaticvoid main(String args[]){

        
String valEmail1 ="[email protected]";
        
String invalEmail1 ="[email protected]";
        
String invalEmail2 =".$$%%@domain.com";
        
String valEmail2 ="[email protected]";

        
System.out.println("Is EmailID1 valid? "+validateEMailID(valEmail1));
        
System.out.println("Is EmailID1 valid? "+validateEMailID(invalEmail1));
        
System.out.println("Is EmailID1 valid? "+validateEMailID(invalEmail2));
        
System.out.println("Is EmailID1 valid? "+validateEMailID(valEmail2));

    
}
    
    
publicstaticboolean validateEMailID(String emailID){
        
Matcher mtch = mypattern.matcher(emailID);
        
if(mtch.matches()){
            
returntrue;
        
}
        
returnfalse;
    
}    
}

1.    Java Swing的简单示例

有了Javaswing,你便可以编写GUI应用了。Java所提供的javax包中就包含了swing。使用swing来编写GUI程序首先需要继承下JFrame。然后在里面添加Box,然后便可以往里面添加诸如按钮,多选按钮,文本框等控件了。这些Box是放在Container的最外层的。

import java.awt.*; 
import javax.swing.*;  

publicclassSwingsDemoextendsJFrame 
{ 
    
publicSwingsDemo() 
    
{
        
String path ="//home//user//Documents//images";
        
Container contentPane = getContentPane(); 
        contentPane
.setLayout(newFlowLayout());   
        
        
Box myHorizontalBox=Box. createHorizontalBox();  
        
Box myVerticleBox =Box.createVerticalBox();   
        
        myHorizontalBox
.add(newJButton("My Button 1")); 
        myHorizontalBox
.add(newJButton("My Button 2")); 
        myHorizontalBox
.add(newJButton("My Button 3"));   

        myVerticleBox
.add(newJButton(newImageIcon(path +"//Image1.jpg"))); 
        myVerticleBox
.add(newJButton(newImageIcon(path +"//Image2.jpg"))); 
        myVerticleBox
.add(newJButton(newImageIcon(path +"//Image3.jpg")));   
        
        contentPane
.add(myHorizontalBox); 
        contentPane
.add(myVerticleBox);   
        
        pack
(); 
        setVisible
(true);
    
} 
    
    
publicstaticvoid main(String args[]){ 
        
newSwingsDemo(); 
    
}  
}

1.    使用Java播放音频

Java中,播放音频是一个很常见的需求,尤其是在游戏开发里面。

下面这个DEMO演示了如何在Java中播放音频。

import java.io.*;
import java.net.URL;
import javax.sound.sampled.*;
import javax.swing.*;

// To play soundusing Clip, the process need to be alive.
// Hence, we usea Swing application.
publicclass playSoundDemo extendsJFrame{

   
// Constructor
   
public playSoundDemo(){
      
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      
this.setTitle("Play Sound Demo");
      
this.setSize(300,200);
      
this.setVisible(true);

      
try{
         URL url 
=this.getClass().getResource("MyAudio.wav");
         
AudioInputStream audioIn =AudioSystem.getAudioInputStream(url);
         
Clip clip =AudioSystem.getClip();
         clip
.open(audioIn);
         clip
.start();
      
}catch(UnsupportedAudioFileException e){
         e
.printStackTrace();
      
}catch(IOException e){
         e
.printStackTrace();
      
}catch(LineUnavailableException e){
         e
.printStackTrace();
      
}
   
}

   
publicstaticvoid main(String[] args){
      
new playSoundDemo();
   
}
}

1.    导出PDF文件

将表格导出成pdf也是一个比较常见的需求。通过itextpdf,导出pdf也不是什么难事。

import java.io.FileOutputStream;
import com.itextpdf.text.Document;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

publicclassDrawPdf{

      
publicstaticvoid main(String[] args)throwsException{
        
Document document =newDocument();
        
PdfWriter.getInstance(document,newFileOutputStream("Employee.pdf"));
        document
.open();
        
        
Paragraph para =newParagraph("Employee Table");
        para
.setSpacingAfter(20);
        document
.add(para);
        
        
PdfPTable table =newPdfPTable(3);
        
PdfPCell cell =newPdfPCell(newParagraph("FirstName"));

        table
.addCell(cell);
        table
.addCell("Last Name");
        table
.addCell("Gender");
        table
.addCell("Ram");
        table
.addCell("Kumar");
        table
.addCell("Male");
        table
.addCell("Lakshmi");
        table
.addCell("Devi");
        table
.addCell("Female");

        document
.add(table);
        
        document
.close();
      
}
    
}

1.    邮件发送

Java中发送邮件也很简单。你只需装一下Java Mail这个jar包,放到你的类路径里即可。在下面的代码中,我们设置了几个基础属性,然后便可以发送邮件了:

import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;

publicclassSendEmail
{
    
publicstaticvoid main(String[] args)
    
{    
        
String to ="[email protected]";
        
Stringfrom="[email protected]";
        
String host ="localhost";

        
Properties properties =System.getProperties();
        properties
.setProperty("mail.smtp.host", host);
        
Session session =Session.getDefaultInstance(properties);

        
try{
            
MimeMessage message =newMimeMessage(session);
            message
.setFrom(newInternetAddress(from));

            message
.addRecipient(Message.RecipientType.TO,newInternetAddress(to));

            message
.setSubject("My EmailSubject");
            message
.setText("My MessageBody");
            
Transport.send(message);
            
System.out.println("Sent successfully!");
        
}
        
catch(MessagingException ex){
            ex
.printStackTrace();
        
}
    
}
}

1.    计算时间

许多程序都需要精确的时间计量。Java提供了一个System的静态方法来支持这一功能:

currentTimeMillis():返回当前时间自新纪元时间以来的毫秒值,long类型。

long startTime =System.currentTimeMillis();
long estimatedTime =System.currentTimeMillis()- startTime;

nanoTime():返回系统计时器当前的精确时间,纳秒值,这也是long类型。nanoTime()主要是用于计算相对时间而非绝对时间。

long startTime =System.nanoTime();
long estimatedTime =System.nanoTime()- startTime;

1.    图片缩放

图片缩放可以通过AffineTransform来完成。首先要生成一个输入图片的图片缓冲,然后通过它来渲染出缩放后的图片。

import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;

publicclassRescaleImage{
  
publicstaticvoid main(String[] args)throwsException{
    
BufferedImage imgSource =ImageIO.read(newFile("images//Image3.jpg"));
    
BufferedImage imgDestination =newBufferedImage(100,100,BufferedImage.TYPE_INT_RGB);
    Graphics2D g 
= imgDestination.createGraphics();
    
AffineTransform affinetransformation =AffineTransform.getScaleInstance(2,2);
    g
.drawRenderedImage(imgSource, affinetransformation);
    
ImageIO.write(imgDestination,"JPG",newFile("outImage.jpg"));
  
}
}

1.    捕获鼠标动作

实现了MouseMotionListner接口后,便可以捕获鼠标事件了。当鼠标进入到某个特定区域时便会触发MouseMoved事件,你便能捕获到这个移动的动作了。通过一个例子来看下:

import java.awt.event.*;
import javax.swing.*;

publicclassMouseCaptureDemoextendsJFrameimplementsMouseMotionListener
{
    
publicJLabel mouseHoverStatus;

    
publicstaticvoid main(String args[]) 
    
{
        
newMouseCaptureDemo();
    
}

    
MouseCaptureDemo() 
    
{
        setSize
(500,500);
        setTitle
("Frame displaying Coordinates of Mouse Motion");

        mouseHoverStatus 
=newJLabel("No Mouse Hover Detected.",JLabel.CENTER);
        add
(mouseHoverStatus);
        addMouseMotionListener
(this);
        setVisible
(true);
    
}

    
publicvoid mouseMoved(MouseEvent e) 
    
{
        mouseHoverStatus
.setText("MouseCursor Coordinates => X:"+e.getX()+" | Y:"+e.getY());
    
}

    
publicvoid mouseDragged(MouseEvent e) 
    
{}
}

1.    FileOutputStreamVs. FileWriter

Java中有两种写文件的方式:FileOutputStreamFileWriter。开发人员经常会在它们之间犹豫不决。下面这个例子能帮忙你更好地理解在不同的场景下应该选择何种方案。首先我们来看一下实现:

使用FileOutputStream

File foutput =newFile(file_location_string);
FileOutputStream fos =newFileOutputStream(foutput);
BufferedWriter output =newBufferedWriter(newOutputStreamWriter(fos));
output
.write("Buffered Content");

使用FileWriter

FileWriter fstream =newFileWriter(file_location_string);
BufferedWriter output =newBufferedWriter(fstream);
output
.write("Buffered Content");

根据Java的接口规范:

FileOutputStream是用于写入原始字节流比如图片流数据。如果是要写入字符流,则应该考虑使用FileWriter

这样就很清楚了,写图片应该使用FileOutputStream而写文本则应该选择FileWriter

附加建议

1.    集合的使用

Java提供了许多集合类——比如,VectorStackHashtable等。所以鼓励开发人员尽可能地使用这些集合类有如下原因:

·        使用集合使得代码的可重用度更高。

·        集合类使得代码的结构更良好,更易于理解与维护。

·        最重要的是这些集合类都经过充分的测试,代码质量很高。

1.    1-50-500规则

在大型软件系统中,代码的可维护性是件很有挑战的工作。新加入的开发人员经常会抱怨这些情况:单片代码(Monolithic Code,意大利面式代码(spaghetti code, 常用于描述捆绑在一起并且低内聚的类和方法)。保持代码的整洁与可维护有一条很简单的规则:

·        10:包内的类不超过10

·        50:方法的代码行数不超过50

·        500:类的代码行数不超过500

1.    SOLID设计准则

2.    SOLIDRobert Martin提出的一套设计准则的简称。根据他的准则:

一个类应当有仅只有一个任务/职责。执行多个任务的类会让人觉得困惑。

单一职责原则

开闭原则

开发人员应当优先考虑扩展现有的软件功能,而不是是修改它。

里氏替换原则

子类必须能够替换掉他们的父类型

接口隔离原则

和单一职责原则类似,但它特指的是接口层。每个接口都应当只负责一项任务。

依赖反转原则

依赖抽象而不是具体实现。也就是说每个模块都应当通过一个抽象层与其它模块进行解耦。

1.    设计模式的使用

设计模式能帮助开发人员更好地在软件中应用软件的设计准则。它还为开发人员提供了跨语言的通用平台。设计模式中的标准术语能让开发人员更容易进行沟通。

1.    关于文档

不要上来就开始写代码。制定计划,准备,编写文档,检查然后再去实现。首先,先把需求记下来。然后去准备设计文档。合理地去假设举证。互相review方案然后进行确认。

1.    使用equals而非==

==是用来比较对象引用的,它会检查两个操作数指向的是不是同一个对象(不是相同的对象,而是同一个对象)。而”equals”则比较的是两个字符串是不是相同(假设是字符串对象)。

1.    避免使用浮点数

只有当确实有必要的时候才使用浮点数。比方说,使用浮点数来表示卢比或者派萨就很容易产生问题——这种情况应当使用BigDecimal。而浮点数更多地是用于测量。

 

你可能感兴趣的:(java初学者常见问题(2))