java 8入门与实践_30个Java入门技巧和最佳实践

java 8入门与实践

Java是最流行的编程语言之一-无论是Win应用程序,Web应用程序,移动,网络,消费电子产品,机顶盒设备,Java随处可见。

在Java上运行的设备超过30亿。 据Oracle称 ,正在使用50亿张Java卡。

超过900万开发人员选择用Java编写代码,该代码在开发人员中非常流行,同时也是最流行的开发平台。

对于即将到来的Java开发人员,此博客提供了一段时间内已学习的最佳实践的集合:

1.最好返回空集合而不是空

如果程序返回的集合没有任何值,请确保返回Empty集合而不是Null元素。 这样可以节省大量对Null Elements进行的“ if else ”测试。

public class getLocationName {
	return (null==cityName ? "": cityName);
}

2.小​​心使用琴弦

如果在“ for”循环中使用“ +”运算符连接了两个字符串,则每次都会创建一个新的字符串对象。 这会导致内存浪费并增加性能时间。 另外,在实例化String对象时,应避免构造函数,而应直接进行实例化。 例如:

//Slower Instantiation
String bad = new String("Yet another string object");
	 
//Faster Instantiation
String good = "Yet another string object"

3.避免不必要的物体

对象创建是Java中最昂贵的操作(就内存利用率而言)。 因此,建议仅在必要时才创建或初始化对象。 以下代码给出了一个示例:

import java.util.ArrayList;
import java.util.List;

public class Employees {

	private List Employees;

	public List getEmployees() {

		//initialize only when required
		if(null == Employees) {
			Employees = new ArrayList();
		}
		return Employees;
	}
}

4. Array和ArrayList之间的困境

开发人员经常发现很难决定是否应该使用ArrayList类型的Array类型数据结构。 他们都有自己的优点和缺点。 选择实际上取决于要求。

import java.util.ArrayList;

public class arrayVsArrayList {

	public static void main(String[] args) {
		int[] myArray = new int[6];
		myArray[7]= 10; // ArraysOutOfBoundException

		//Declaration of ArrayList. Add and Remove of elements is easy.
		ArrayList<Integer> myArrayList = new ArrayList<>();
		myArrayList.add(1);
		myArrayList.add(2);
		myArrayList.add(3);
		myArrayList.add(4);
		myArrayList.add(5);
		myArrayList.remove(0);
		
		for(int i = 0; i < myArrayList.size(); i++) {
		System.out.println("Element: " + myArrayList.get(i));
		}
		
		//Multi-dimensional Array 
		int[][][] multiArray = new int [3][3][3]; 
	}
}
  1. 数组的大小固定,但ArrayList的大小可变。 由于Array的大小是固定的,因此在声明Array类型变量时会分配内存。 因此,数组非常快。 另一方面,如果我们不知道数据的大小,那么ArrayList为:更多数据将导致ArrayOutOfBoundException,而较少数据将导致存储空间的浪费。
  2. 从ArrayList添加或删除元素比Array要容易得多
  3. 数组可以是多维的,但ArrayList只能是一维的。

5.最终无法通过Try执行时

考虑以下代码段:

public class shutDownHooksDemo {
	public static void main(String[] args) {
		for(int i=0;i<5;i++)
		{
			try {
				if(i==4) {
					System.out.println("Inside Try Block.Exiting without executing Finally block.");
					System.exit(0);
				}
			}
			finally {
				System.out.println("Inside Finally Block.");
			}
		}
	}
}

在程序中, finally块中的“ println”看起来将执行5次。 但是,如果执行该程序,则用户会发现, finally块仅被调用了4次。 在第五次迭代中, 退出函数将被调用, 最后再也不会被第五次调用。 原因是-System.exit暂停所有正在运行的线程(包括当前线程)的执行。 在尝试执行退出后,即使finally块也无法执行。

调用System.exit时 ,JVM在关闭之前执行两项清理任务:

首先,它执行所有已向Runtime.addShutdownHook注册的关机钩子 。 这非常有用,因为它释放了JVM外部的资源。

其次是与终结器有关。 System.runFinalizersOnExitRuntime.runFinalizersOnExit终结器的使用从很久以前就已被弃用。 终结器可以在由其他线程操纵的活动对象上运行,这会导致不良结果甚至死锁。

public class shutDownHooksDemo {

    public static void main(String[] args) {
            for(int i=0;i<5;i++)
            {
                    final int final_i = i;
                    try {
                            Runtime.getRuntime().addShutdownHook(
                                            new Thread() {
                                            public void run() {
                                            if(final_i==4) {
                                            System.out.println("Inside Try Block.Exiting without executing Finally block.");
                                            System.exit(0);
                                            }
                                            }
                                            });
                    }
                    finally {
                            System.out.println("Inside Finally Block.");
                    }

            }
    }
}

6.检查可能性

看看下面的代码行,确定它们是否可以用来精确识别给定的数字是否为奇数?

public boolean oddOrNot(int num) {
	return num % 2 == 1;
}

这些行看似正确,但是每四次将返回一次错误的结果(从统计意义上来说)。 考虑一个负的奇数,除以2的余数将不是1。因此,返回的结果将为false,这是不正确的!

可以固定如下:

public boolean oddOrNot(int num) {
	return (num & 1) != 0;
}

使用此代码,不仅可以解决负奇数的问题,而且可以对代码进行高度优化。 由于算术和逻辑运算与除法和乘法相比要快得多,因此在第二个代码段中,可以更快地获得结果。

7.单引号和双引号之间的区别

public class Haha {
	public static void main(String args[]) {
	System.out.print("H" + "a");
	System.out.print('H' + 'a');
	}
}

从代码看,似乎返回了“ HaHa”,但实际上返回了Ha169。 原因是,如果使用双引号,则将字符视为字符串,但如果使用单引号,则将char值的操作数(“ H”和“ a”)通过称为加宽基元转换的过程转换为int值。 整数转换后,将数字相加并返回169。

8.通过简单的技巧避免内存泄漏

内存泄漏通常会导致软件性能下降。 由于Java自动管理内存,因此开发人员没有太多控制权。 但是仍然有一些标准做法可以用来防止内存泄漏。

  • 查询完成后,请始终释放数据库连接。
  • 尝试尽可能经常使用Final块。
  • 释放存储在静态表中的实例。

9.避免Java中的死锁

死锁的发生可能有多种原因。 没有避免死锁的单一方法。 通常,当一个同步对象正在等待另一同步对象锁定的资源上的锁时,就会发生死锁。

尝试运行以下程序。 该程序演示了死锁。 之所以会出现此死锁,是因为两个线程都在等待其他线程获取的资源。 他们俩都在等待,没有人释放。

public class DeadlockDemo {
   public static Object addLock = new Object();
   public static Object subLock = new Object();

   public static void main(String args[]) {

      MyAdditionThread add = new MyAdditionThread();
      MySubtractionThread sub = new MySubtractionThread();
      add.start();
      sub.start();
   }
private static class MyAdditionThread extends Thread {
      public void run() {
         synchronized (addLock) {
		int a = 10, b = 3;
		int c = a + b;
            System.out.println("Addition Thread: " + c);
            System.out.println("Holding First Lock...");
            try { Thread.sleep(10); }
            catch (InterruptedException e) {}
            System.out.println("Addition Thread: Waiting for AddLock...");
            synchronized (subLock) {
               System.out.println("Threads: Holding Add and Sub Locks...");
            }
         }
      }
   }
   private static class MySubtractionThread extends Thread {
      public void run() {
         synchronized (subLock) {
		int a = 10, b = 3;
		int c = a - b;
            System.out.println("Subtraction Thread: " + c);
            System.out.println("Holding Second Lock...");
            try { Thread.sleep(10); }
            catch (InterruptedException e) {}
            System.out.println("Subtraction  Thread: Waiting for SubLock...");
            synchronized (addLock) {
               System.out.println("Threads: Holding Add and Sub Locks...");
            }
         }
      }
   }
}
输出:
=====
Addition Thread: 13
Subtraction Thread: 7
Holding First Lock...
Holding Second Lock...
Addition Thread: Waiting for AddLock...
Subtraction  Thread: Waiting for SubLock...

但是,如果更改了调用线程的顺序,则可以解决死锁问题。

public class DeadlockSolutionDemo {
   public static Object addLock = new Object();
   public static Object subLock = new Object();

   public static void main(String args[]) {

      MyAdditionThread add = new MyAdditionThread();
      MySubtractionThread sub = new MySubtractionThread();
      add.start();
      sub.start();
   }


private static class MyAdditionThread extends Thread {
      public void run() {
         synchronized (addLock) {
		int a = 10, b = 3;
		int c = a + b;
            System.out.println("Addition Thread: " + c);
            System.out.println("Holding First Lock...");
            try { Thread.sleep(10); }
            catch (InterruptedException e) {}
            System.out.println("Addition Thread: Waiting for AddLock...");
            synchronized (subLock) {
               System.out.println("Threads: Holding Add and Sub Locks...");
            }
         }
      }
   }
   
   private static class MySubtractionThread extends Thread {
      public void run() {
         synchronized (addLock) {
		int a = 10, b = 3;
		int c = a - b;
            System.out.println("Subtraction Thread: " + c);
            System.out.println("Holding Second Lock...");
            try { Thread.sleep(10); }
            catch (InterruptedException e) {}
            System.out.println("Subtraction  Thread: Waiting for SubLock...");
            synchronized (subLock) {
               System.out.println("Threads: Holding Add and Sub Locks...");
            }
         }
      }
   }
}
输出:
=====
Addition Thread: 13
Holding First Lock...
Addition Thread: Waiting for AddLock...
Threads: Holding Add and Sub Locks...
Subtraction Thread: 7
Holding Second Lock...
Subtraction  Thread: Waiting for SubLock...
Threads: Holding Add and Sub Locks...

10.为Java保留内存

一些Java应用程序可能会占用大量CPU,并且需要大量RAM。 由于较高的RAM需求,此类应用程序通常运行缓慢。 为了提高此类应用程序的性能,RAM保留用于Java。 因此,例如,如果我们有一个Tomcat Web服务器,并且它具有10 GB的RAM。 如果愿意,可以使用以下命令在此计算机上为Java分配RAM:

export JAVA_OPTS="$JAVA_OPTS -Xms5000m -Xmx6000m -XX:PermSize=1024m -XX:MaxPermSize=2048m"
  • Xms =最小内存分配池
  • Xmx =最大内存分配池
  • XX:PermSize =将在JVM启动期间分配的初始大小
  • XX:MaxPermSize = JVM启动期间可以分配的最大大小

11.如何对Java中的操作进行计时

Java中有两种计时操作的标准方式: System.currentTimeMillis()System.nanoTime()问题是,选择哪种方式以及在什么情况下。 原则上,它们都执行相同的操作,但在以下方面有所不同:

  1. System.currentTimeMillis需要大约1/1000秒到15/1000秒之间的时间(取决于系统),但是System.nanoTime()需要大约1 / 1000,000秒的时间(1,000纳秒)
  2. System.currentTimeMillis需要几个时钟周期来执行读取操作。 另一方面,System.nanoTime()需要100多个时钟周期。
  3. System.currentTimeMillis反映绝对时间(自1970年1月1日以来的毫秒数00:00(Epoch时间)),但是System.nanoTime()不一定代表任何参考点。

12.浮动和双精度之间的选择

数据类型 使用的字节数 有效数字(十进制)
浮动 4 7
8 15

在精度很重要的软件中,Double通常优于float,这是因为以下原因:

大多数处理器在Float和Double上执行操作所需的处理时间几乎相同。 Double在相同的计算时间内提供了更高的精度。

13.功率计算

为了计算功效(^),java执行异或(XOR)。 为了计算能力,Java提供了两种选择:

  1. 乘法:
    double square = double a * double a;							// Optimized
    double cube = double a * double a * double a; 					// Non-optimized
    double cube = double a * double square; 						// Optimized
    double quad = double a * double a * double a * double a;	 		// Non-optimized
    double quad = double square * double square; 					// Optimized
  2. pow(double base,double exponent): 'pow'方法用于计算不可能进行乘法的地方(base ^ exponent)
    double cube = Math.pow(base, exponent);

仅在必要时才使用Math.pow。 例如,指数是一个小数值。 这是因为Math.pow()方法通常比乘法慢300-600倍。

14.如何处理空指针异常

空指针异常在Java中很常见。 当我们尝试在空对象引用上调用方法时,会发生此异常。 例如,

int noOfStudents = school.listStudents().count;

如果在上面的示例中,如果获得NullPointerException,则school为null或listStudents()为Null。 尽早检查Null是个好主意,这样就可以消除它们。

private int getListOfStudents(File[] files) {
	  if (files == null)
	    throw new NullPointerException("File list cannot be null");
	}

15.用JSON编码

JSON(JavaScript对象表示法)是用于存储和交换数据的语法。 JSON是XML的一种易于使用的替代方法。 如今,由于其特性和重量轻,Json在Internet上变得非常流行。 普通的数据结构可以编码为JSON,并可以轻松地在网页上共享。 在开始编写代码之前,必须先安装JSON解析器。 在以下示例中,我们使用了json.simple(https://code.google.com/p/json-simple/)。

以下是编码为JSON的基本示例:

import org.json.simple.JSONObject;
import org.json.simple.JSONArray;

public class JsonEncodeDemo {
	
	public static void main(String[] args) {
		
        JSONObject obj = new JSONObject();
        obj.put("Novel Name", "Godaan");
        obj.put("Author", "Munshi Premchand");
 
        JSONArray novelDetails = new JSONArray();
        novelDetails.add("Language: Hindi");
        novelDetails.add("Year of Publication: 1936");
        novelDetails.add("Publisher: Lokmanya Press");
        
        obj.put("Novel Details", novelDetails);
        
		System.out.print(obj);
	}
}
输出:
{"Novel Name":"Godaan","Novel Details":["Language: Hindi","Year of Publication: 1936","Publisher: Lokmanya Press"],"Author":"Munshi Premchand"}

16.从JSON解码

为了解码JSON,开发人员必须了解该架构。 可以在下面的示例中找到详细信息:

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

public class JsonParseTest {

	private static final String filePath = "//home//user//Documents//jsonDemoFile.json";
	
	public static void main(String[] args) {

		try {
			// read the json file
			FileReader reader = new FileReader(filePath);
			JSONParser jsonParser = new JSONParser();
			JSONObject jsonObject = (JSONObject)jsonParser.parse(reader);
			
			// get a number from the JSON object
			Long id =  (Long) jsonObject.get("id");
			System.out.println("The id is: " + id);			

			// get a String from the JSON object
			String	type = (String) jsonObject.get("type");
			System.out.println("The type is: " + type);

			// get a String from the JSON object
			String	name = (String) jsonObject.get("name");
			System.out.println("The name is: " + name);

			// get a number from the JSON object
			Double ppu =  (Double) jsonObject.get("ppu");
			System.out.println("The PPU is: " + ppu);
			
			// get an array from the JSON object
			System.out.println("Batters:");
			JSONArray batterArray= (JSONArray) jsonObject.get("batters");
			Iterator i = batterArray.iterator();
			// take each value from the json array separately
			while (i.hasNext()) {
				JSONObject innerObj = (JSONObject) i.next();
				System.out.println("ID "+ innerObj.get("id") + 
						" type " + innerObj.get("type"));
			}

			// get an array from the JSON object
			System.out.println("Topping:");
			JSONArray toppingArray= (JSONArray) jsonObject.get("topping");
			Iterator j = toppingArray.iterator();
			// take each value from the json array separately
			while (j.hasNext()) {
				JSONObject innerObj = (JSONObject) j.next();
				System.out.println("ID "+ innerObj.get("id") + 
						" type " + innerObj.get("type"));
			}
			

		} catch (FileNotFoundException ex) {
			ex.printStackTrace();
		} catch (IOException ex) {
			ex.printStackTrace();
		} catch (ParseException ex) {
			ex.printStackTrace();
		} catch (NullPointerException ex) {
			ex.printStackTrace();
		}

	}

}

jsonDemoFile.json

{
	"id": 0001,
	"type": "donut",
	"name": "Cake",
	"ppu": 0.55,
	"batters":
		[
			{ "id": 1001, "type": "Regular" },
			{ "id": 1002, "type": "Chocolate" },
			{ "id": 1003, "type": "Blueberry" },
			{ "id": 1004, "type": "Devil's Food" }
		],
	"topping":
		[
			{ "id": 5001, "type": "None" },
			{ "id": 5002, "type": "Glazed" },
			{ "id": 5005, "type": "Sugar" },
			{ "id": 5007, "type": "Powdered Sugar" },
			{ "id": 5006, "type": "Chocolate with Sprinkles" },
			{ "id": 5003, "type": "Chocolate" },
			{ "id": 5004, "type": "Maple" }
		]
}
The id is: 1
The type is: donut
The name is: Cake
The PPU is: 0.55
Batters:
ID 1001 type Regular
ID 1002 type Chocolate
ID 1003 type Blueberry
ID 1004 type Devil's Food
Topping:
ID 5001 type None
ID 5002 type Glazed
ID 5005 type Sugar
ID 5007 type Powdered Sugar
ID 5006 type Chocolate with Sprinkles
ID 5003 type Chocolate
ID 5004 type Maple

17.简单的字符串搜索

Java提供了一个称为indexOf()的Library方法。 此方法与String Object一起使用,它返回所需字符串的索引位置。 如果找不到该字符串,则返回-1。

public class StringSearch {

	public static void main(String[] args) {
		String myString = "I am a String!";
		
		if(myString.indexOf("String") == -1) {
			System.out.println("String not Found!");
		}
		else {
			System.out.println("String found at: " + myString.indexOf("String"));
		}
	}
}

18.列出目录的内容

为了列出目录的内容,可以使用以下程序。 该程序仅接收Array文件夹中所有子目录和文件的名称,然后顺序遍历该数组以列出所有内容。

import java.io.*;

public class ListContents {
	public static void main(String[] args) {
		File file = new File("//home//user//Documents/");
		String[] files = file.list();

		System.out.println("Listing contents of " + file.getPath());
		for(int i=0 ; i < files.length ; i++)
		{
			System.out.println(files[i]);
		}
	}
}

19.一个简单的IO

为了读取文件并写入文件,Java提供了FileInputStream和FileOutputStream类。 FileInputStream的构造函数接受Input File的文件路径作为参数并创建File Input Stream。 同样,FileOutputStream的构造函数接受Output File的文件路径作为参数并创建File Output Stream。完成文件处理后,“关闭”流很重要。

import java.io.*;

public class myIODemo {
	public static void main(String args[]) throws IOException {
		FileInputStream in = null;
		FileOutputStream out = null;
		
		try {
			in = new FileInputStream("//home//user//Documents//InputFile.txt");
			out = new FileOutputStream("//home//user//Documents//OutputFile.txt");
			
			int c;
			while((c = in.read()) != -1) {
				out.write(c);
			}
		} finally {
			if(in != null) {
				in.close();
			}
			if(out != null) {
				out.close();
			}
		}
	}
}

20.从Java执行shell命令

Java提供了Runtime类来执行Shell命令。 由于这些是外部命令,因此异常处理非常重要。 在下面的示例中,我们通过一个简单的示例进行说明。 我们正在尝试从Shell命令打开PDF文件。

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

public class ShellCommandExec {

	public static void main(String[] args) {
		String gnomeOpenCommand = "gnome-open //home//user//Documents//MyDoc.pdf";

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

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

			String myoutput = "";

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

21.使用正则表达式

正则表达式构造摘要(来源:Oracle网站)
性格
X 字符x
\\ 反斜杠字符
\ 0n 八进制值0n(0 <= n <= 7)的字符
\ 0nn 八进制值0nn(0 <= n <= 7)的字符
\ 0mnn 八进制值0mnn的字符(0 <= m <= 3,0 <= n <= 7)
\ xhh 十六进制值为0xhh的字符
\ uhhhh 十六进制值为0xhhhh的字符
\ x {h…h} 十六进制值为0xh…h的字符(Character.MIN_CODE_POINT <= 0xh…h <= Character.MAX_CODE_POINT)
\ t 制表符('\ u0009')
\ n 换行符('\ u000A')
\ r 回车符('\ u000D')
\F 换页字符('\ u000C')
\一个 警报(响铃)字符('\ u0007')
\ e 转义符('\ u001B')
\ cx 与x对应的控制字符

角色类
[abc] a,b或c(简单类)
[^ abc] 除a,b或c(取反)之外的任何字符
[a-zA-Z] a到z或A到Z(含)(范围)
[ad [mp]] a到d,或m到p:[a-dm-p](联合)
[az && [def]] d,e或f(交叉点)
[az && [^ bc]] a到z,b和c除外:[ad-z](减法)
[az && [^ mp]] a到z,而不是m到p:[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 单词边界
\ B 非单词边界
\一个 输入的开始
\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;
	} 	
}

22.简单的Java Swing示例

借助Java Swing GUI可以创建。 Java提供了包含“ swing”的Javax。 使用swing的GUI从扩展JFrame开始。 添加了框,以便它们可以包含GUI组件,例如Button,单选按钮,文本框等。这些框设置在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(); 
	}  
}

23.用Java播放声音

播放声音是Java中的常见要求,尤其是与游戏一起使用时。

本演示说明了如何播放音频文件以及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();
   }
}

24. PDF导出

将表导出为PDF是Java程序中的常见要求。 使用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();
	  }
	}

25.从Java代码发送电子邮件

从Java发送电子邮件很简单。 我们需要安装Java Mail Jar,并在程序的classpath中设置其路径。 基本属性是在代码中设置的,我们很高兴发送电子邮件,如下面的代码所述:

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();
		}
	}
}

26.测量时间

许多应用需要非常精确的时间测量。 为此,Java在System类中提供了静态方法:

  1. currentTimeMillis():以“纪元时间”为单位,以毫秒为单位返回当前时间(以毫秒为单位)。
    long startTime = System.currentTimeMillis();
    long estimatedTime = System.currentTimeMillis() - startTime;
  2. nanoTime():返回最精确的可用系统计时器的当前值(以纳秒为单位)。 nanoTime()用于测量相对时间间隔,而不是提供绝对定时。
    long startTime = System.nanoTime();
    long estimatedTime = System.nanoTime() - startTime;

27.重新缩放图像

可以使用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"));
  }
}

28.捕获鼠标悬停坐标

通过实现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) 
	{}
}

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 API规范:

FileOutputStream用于写入原始字节流,例如图像数据。 要编写字符流,请考虑使用FileWriter。

这清楚表明,对于图像类型的数据应使用FileOutputStream,对于文本类型的数据应使用FileWriter。

其他建议

  1. 使用收藏

    Java附带了一些收集类-例如,Vector,Stack,Hashtable,Array。 出于以下原因,鼓励开发人员尽可能广泛地使用集合:

    • 使用集合可以使代码可重用和互操作。
    • 集合使代码更结构化,更易于理解和维护。
    • 开箱即用的集合类经过了良好的测试,因此代码质量很好。
  2. 10-50-500规则

    在大型软件包中,维护代码变得非常困难。 加入新的正在进行的支持项目的开发人员经常会抱怨: 整体式代码Spaghetti代码 。 有一个非常简单的规则可以避免这种情况,或者保持代码的干净和可维护:10-50-500。

    • 10:任何程序包都不能超过10个类。
    • 50:任何方法都不能超过50行代码。
    • 500:没有一个类可以包含超过500行代码。
  3. SOLID类设计原则

    SOLID(http://zh.wikipedia.org/wiki/SOLID_%28object-oriented_design%29)是Robert Martin提出的设计原则的首字母缩写。 根据此规则:

    规则 描述
    单一责任原则 一堂课应该只有一个任务/职责。 如果班级执行的任务不止一项,则会导致混乱。
    开闭原则 开发人员应更多地专注于扩展软件实体,而不是对其进行修改。
    里斯科夫替代原则 应该可以用基类代替派生类。
    接口隔离原理 就像单一责任原则,但适用于接口。 每个接口应负责一项特定任务。 开发人员应该实现不需要的方法。
    依赖倒置原则 取决于抽象-但不取决于混凝土。 这意味着每个模块都应使用将它们绑定在一起的抽象层将它们分开。
  4. 设计模式的使用

    设计模式可帮助开发人员在其软件中纳入最佳软件设计原则。 它们还为全球的开发人员提供了通用平台。 它们提供了标准术语,使开发人员能够相互协作并更轻松地相互交流。

  5. 记录想法

    永远不要只是开始编写代码。 制定战略,准备,记录,审查和实施。 首先,记下您的要求。 准备设计文件。 适当提及假设。 让文档经过同行评审,并在其上签字。

  6. 在==上使用等于

    ==比较对象引用,它检查两个操作数是否指向相同的对象(不是等效的对象,相同的对象)。另一方面,“等于”执行两个字符串的实际比较。

  7. 避免浮点数

    仅在绝对必要时才应使用浮点数。 例如,使用浮点数表示卢比和帕斯可能会出现问题-应该改用BigDecimal。 浮点数在测量中更有用。

学习Java的最佳资源

另外,我想提到有许多学习Java的资源

翻译自: https://www.javacodegeeks.com/2015/06/java-programming-tips-best-practices-beginners.html

java 8入门与实践

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值