1. 程式人生 > >JAVA中的匿名類、內部類和匿名內部類

JAVA中的匿名類、內部類和匿名內部類

   在看《java核心技術卷I》的時候再TreeSet的章節,看到了使用匿名內部類的例項,好奇後查了下相關資訊,有兩個部落格寫的很好,以後還需細看

先說下TreeSet的Test, TreeSet和Hashset的區別主要是前者是一個有序集合,使用的排序方法時紅黑樹的方法(類似於平衡二叉樹AVL,詳見演算法導論)。在TreeSet中加入java中已定義的類時,如string,則加入時會自動呼叫其已經實現的comparable介面中的compareTo方法(按字母的字典序排列)對字串進行排序。

      但是如果要插入自定義的物件,就必須在對應的類中擴充套件comparable藉口,並且實現其中的compareTo方法。 還有一個方法就是構造一個帶有比較器(Comparator)的樹。兩種比較方法見下面的程式碼:

/*
 * 這個例子主要是練習comparable介面的comepleTo虛擬方法(單引數)和comparator介面的compare虛擬方法(兩個引數)在進行物件比較的時候的差別
 * 此外,TreeSet是一個排序樹,按照紅黑樹的方法進行元素排序(紅黑樹類似於AVL樹)
 */
import java.util.Comparator;
import java.util.SortedSet;
import java.util.TreeSet;

public class TreeSetTest {
	@SuppressWarnings("unchecked")
	public static void main(String[] args)
	{
		SortedSet<Item> parts = new TreeSet<Item>();
		TreeSet<Item> parts2 = new TreeSet<Item>();
		
		/*
		 * part.add的排序是Item類中通過擴充套件comparable介面後實現其compareTo的虛擬方法
		 */
		parts.add(new Item("awhu", 345678123));
		parts.add(new Item("pku", 234));
		parts.add(new Item("duku", 123345));
		parts.add(new Item("shagnhai", 4567));	
		
		//System.out.println(parts.toString());
		System.out.println(parts); //兩者寫法一樣效果,前者顯示定義了物件例項輸出的格式\
		parts2.addAll(parts);
		System.out.println(parts.size());		
		
		SortedSet<Item> sortByDescription = new TreeSet<Item>( new Comparator<Item>() 
		{
			public int compare(Item a, Item b)
			{
				String descrA = a.getDescription();
				String descrB = b.getDescription();
				return descrA.compareTo(descrB); //呼叫string類自身的compareTo方法
			}
		});
		
		/*
		 * sortByDescription.addALL的排序是通過上面定義的帶有比較器的樹 中的比較規則來實現的
		 */
		sortByDescription.addAll(parts);
		System.out.println(sortByDescription);
		
		/*
		 * 上一步中用java匿名內部類定義的帶有比較器comparator的樹可以使用下面結構更為清晰,程式碼可讀性更強的書寫代替
		 */
		
		ItemComparator comp = new ItemComparator();
		SortedSet<Item> SortByDescription2 = new TreeSet<Item>(comp); 
		SortByDescription2.addAll(parts);
		System.out.println(SortByDescription2);
			
	}
		
}

class Item implements Comparable<Item>{
	
	private String description;
	private int partnumber;
	
	public Item(String aDescription, int aPartNumber)
	{
		description = aDescription;
		partnumber = aPartNumber;		
	}
	
	public String getDescription()
	{
		return description;
	}
	
	public String toString()
	{
		return "[desciption=" + description + ",partnumber=" + partnumber + "]";
	}
	
	public boolean equals(Object otherobject)
	{
		if(this == otherobject)
			return true;
		if(otherobject == null)
			return false;
		if(getClass()!= otherobject.getClass())
			return false;
		
		Item other = (Item)otherobject;
		
		return description.equals(other.description) && partnumber == other.partnumber;
	}
	
	public int hashCode()
	{
		return 13*description.hashCode() + 17*partnumber;		
	}
	
	public int compareTo(Item other)  //必須要實現的一個方法
	{
		return partnumber - other.partnumber;
	}	

}

/*前面用java匿名內部類實現的帶有比較器的樹可以先定義一個擴充套件了比較器comparator介面並且實現了其中的compare虛擬方法的類ItemCompare,
 * 然後對該類ItemCompare例項化一個物件com,將這個物件作為TreeSet的建構函式中的 引數(函式物件):SortedSet<Item> SortByDescription2 = new TreeSet<Item>(comp); 
 *  *  */
class ItemComparator implements Comparator<Item>
{
	public int compare(Item a, Item b)
	{
		String descrA = a.getDescription();
		String descrB = b.getDescription();
		return descrA.compareTo(descrB);
	}
}

         其中在定義帶有比較器(comparator)時就使用了匿名內部類。匿名內部類就是在外部類的例項就是在外部類中作為一個函式物件,沒有必要特意為之申請一個變數,使其指向匿名內部類例項的物件。程式碼更為簡潔,但是可讀性降低。

     帶有比較器(comparator)的樹的定義可以採用更為清晰的結構書寫,在程式碼中已有提及。