十七.使用正则
正则表达式的结构摘录如下(来源: 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, b或c |
[^abc] | abc以外的任意字符 |
[a-zA-Z] | a到z以及A到Z |
[a-d[m-p]] | a到d或者m到p[a-dm-p]则是取并集 |
[a-z&&[def]] | d,e或f(交集) |
[ad-z] | |
[a-z&&[^bc]] | a到z但不包括b和c |
[a-z&&[^m-p]] | a到z但不包括mp:也就是[a-lq-z] |
预定义字符
. | 任意字符,有可能包括换行符 |
/d | 0到9的数字 |
/D | 0到9以外的字符 |
/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; public class RegexMatches { private static String pattern = "^[_A-Za-z0-9-]+(//.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(//.[A-Za-z0-9]+)*(//.[A-Za-z]{2,})$"; private static Pattern mypattern = Pattern.compile(pattern); public static void main( String args[] ){ String valEmail1 = "testemail@domain.com"; String invalEmail1 = "....@domain.com"; String invalEmail2 = ".$$%%@domain.com"; String valEmail2 = "test.email@domain.com"; System.out.println("Is Email ID1 valid? "+validateEMailID(valEmail1)); System.out.println("Is Email ID1 valid? "+validateEMailID(invalEmail1)); System.out.println("Is Email ID1 valid? "+validateEMailID(invalEmail2)); System.out.println("Is Email ID1 valid? "+validateEMailID(valEmail2)); } public static boolean validateEMailID(String emailID) { Matcher mtch = mypattern.matcher(emailID); if(mtch.matches()){ return true; } return false; } }
十八.Java Swing的简单示例
有了Java的swing,你便可以编写GUI应用了。Java所提供的javax包中就包含了swing。使用swing来编写GUI程序首先需要继承下JFrame。然后在里面添加Box,然后便可以往里面添加诸如按钮,多选按钮,文本框等控件了。这些Box是放在Container的最外层的。
import java.awt.*; import javax.swing.*; public class SwingsDemo extends JFrame { public SwingsDemo() { String path = "//home//user//Documents//images"; Container contentPane = getContentPane(); contentPane.setLayout(new FlowLayout()); Box myHorizontalBox = Box. createHorizontalBox(); Box myVerticleBox = Box. createVerticalBox(); myHorizontalBox.add(new JButton("My Button 1")); myHorizontalBox.add(new JButton("My Button 2")); myHorizontalBox.add(new JButton("My Button 3")); myVerticleBox.add(new JButton(new ImageIcon(path + "//Image1.jpg"))); myVerticleBox.add(new JButton(new ImageIcon(path + "//Image2.jpg"))); myVerticleBox.add(new JButton(new ImageIcon(path + "//Image3.jpg"))); contentPane.add(myHorizontalBox); contentPane.add(myVerticleBox); pack(); setVisible(true); } public static void main(String args[]) { new SwingsDemo(); } }
十九.使用Java播放音频
在Java中,播放音频是一个很常见的需求,尤其是在游戏开发里面。
下面这个DEMO演示了如何在Java中播放音频。
import java.io.*; import java.net.URL; import javax.sound.sampled.*; import javax.swing.*; // To play sound using Clip, the process need to be alive. // Hence, we use a Swing application. public class playSoundDemo extends JFrame { // 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(); } } public static void main(String[] args) { new playSoundDemo(); } }
二十.导出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; public class DrawPdf { public static void main(String[] args) throws Exception { Document document = new Document(); PdfWriter.getInstance(document, new FileOutputStream("Employee.pdf")); document.open(); Paragraph para = new Paragraph("Employee Table"); para.setSpacingAfter(20); document.add(para); PdfPTable table = new PdfPTable(3); PdfPCell cell = new PdfPCell(new Paragraph("First Name")); 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(); } }
二十一.邮件发送
在Java中发送邮件也很简单。你只需装一下Java Mail这个jar包,放到你的类路径里即可。在下面的代码中,我们设置了几个基础属性,然后便可以发送邮件了:
import java.util.*; import javax.mail.*; import javax.mail.internet.*; public class SendEmail { public static void main(String [] args) { String to = "recipient@gmail.com"; String from = "sender@gmail.com"; String host = "localhost"; Properties properties = System.getProperties(); properties.setProperty("mail.smtp.host", host); Session session = Session.getDefaultInstance(properties); try{ MimeMessage message = new MimeMessage(session); message.setFrom(new InternetAddress(from)); message.addRecipient(Message.RecipientType.TO,new InternetAddress(to)); message.setSubject("My Email Subject"); message.setText("My Message Body"); Transport.send(message); System.out.println("Sent successfully!"); } catch (MessagingException ex) { ex.printStackTrace(); } } }
二十二.计算时间
许多程序都需要精确的时间计量。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;
二十三.图片缩放
图片缩放可以通过AffineTransform来完成。首先要生成一个输入图片的图片缓冲,然后通过它来渲染出缩放后的图片。
import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; public class RescaleImage { public static void main(String[] args) throws Exception { BufferedImage imgSource = ImageIO.read(new File("images//Image3.jpg")); BufferedImage imgDestination = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); Graphics2D g = imgDestination.createGraphics(); AffineTransform affinetransformation = AffineTransform.getScaleInstance(2, 2); g.drawRenderedImage(imgSource, affinetransformation); ImageIO.write(imgDestination, "JPG", new File("outImage.jpg")); } }
二十四.捕获鼠标动作
实现了MouseMotionListner接口后,便可以捕获鼠标事件了。 当鼠标进入到某个特定区域时便会触发MouseMoved事件,你便能捕获到这个移动的动作了。通过一个例子来看下:
import java.awt.event.*; import javax.swing.*; public class MouseCaptureDemo extends JFrame implements MouseMotionListener { public JLabel mouseHoverStatus; public static void main(String args[]) { new MouseCaptureDemo(); } MouseCaptureDemo() { setSize(500, 500); setTitle("Frame displaying Coordinates of Mouse Motion"); mouseHoverStatus = new JLabel("No Mouse Hover Detected.", JLabel.CENTER); add(mouseHoverStatus); addMouseMotionListener(this); setVisible(true); } public void mouseMoved(MouseEvent e) { mouseHoverStatus.setText("Mouse Cursor Coordinates => X:"+e.getX()+" | Y:"+e.getY()); } public void mouseDragged(MouseEvent e) {} }
二十五.FileOutputStream Vs. FileWriter
在Java中有两种写文件的方式:FileOutputStream与FileWriter。开发人员经常会在它们之间犹豫不决。下面这个例子能帮忙你更好地理解在不同的场景下应该选择何种方案。首先我们来看一下实现:
使用FileOutputStream:
File foutput = new File(file_location_string); FileOutputStream fos = new FileOutputStream(foutput); BufferedWriter output = new BufferedWriter(new OutputStreamWriter(fos)); output.write("Buffered Content");
使用FileWriter:
FileWriter fstream = new FileWriter(file_location_string); BufferedWriter output = new BufferedWriter(fstream); output.write("Buffered Content");
根据Java的接口规范:
FileOutputStream是用于写入原始字节流比如图片流数据。如果是要写入字符流,则应该考虑使用FileWriter。
这样就很清楚了,写图片应该使用FileOutputStream而写文本则应该选择FileWriter。
附加建议
①.集合的使用
Java提供了许多集合类——比如,Vector,Stack,Hashtable等。所以鼓励开发人员尽可能地使用这些集合类有如下原因:
- 使用集合使得代码的可重用度更高。
- 集合类使得代码的结构更良好,更易于理解与维护。
- 最重要的是这些集合类都经过充分的测试,代码质量很高。
②.1-50-500规则
在大型软件系统中,代码的可维护性是件很有挑战的工作。新加入的开发人员经常会抱怨这些情况:单片代码(Monolithic Code),意大利面式代码(spaghetti code, 常用于描述捆绑在一起并且低内聚的类和方法)。保持代码的整洁与可维护有一条很简单的规则:
- 10:包内的类不超过10个
- 50:方法的代码行数不超过50
- 500:类的代码行数不超过500
- SOLID设计准则
- SOLID是Robert Martin提出的一套设计准则的简称。根据他的准则:
一个类应当有仅只有一个任务/职责。执行多个任务的类会让人觉得困惑。
单一职责原则 | |
开闭原则 | 开发人员应当优先考虑扩展现有的软件功能,而不是是修改它。 |
里氏替换原则 | 子类必须能够替换掉他们的父类型 |
接口隔离原则 | 和单一职责原则类似,但它特指的是接口层。每个接口都应当只负责一项任务。 |
依赖反转原则 | 依赖抽象而不是具体实现。也就是说每个模块都应当通过一个抽象层与其它模块进行解耦。 |
③.设计模式的使用
设计模式能帮助开发人员更好地在软件中应用软件的设计准则。它还为开发人员提供了跨语言的通用平台。设计模式中的标准术语能让开发人员更容易进行沟通。
④.关于文档
不要上来就开始写代码。制定计划,准备,编写文档,检查然后再去实现。首先,先把需求记下来。然后去准备设计文档。合理地去假设举证。互相review方案然后进行确认。
⑤.使用equals而非==
==是用来比较对象引用的,它会检查两个操作数指向的是不是同一个对象(不是相同的对象,而是同一个对象)。而”equals”则比较的是两个字符串是不是相同(假设是字符串对象)。
⑥.避免使用浮点数
只有当确实有必要的时候才使用浮点数。比方说,使用浮点数来表示卢比或者派萨就很容易产生问题——这种情况应当使用BigDecimal。而浮点数更多地是用于测量。