Java编程思想学习笔记(三)
(美) Bruce Eckel 著 《Java编程思想》部分学习日记(随手记录的笔记)
15. 内部类概念:
当生成一个内部类的对象时,此对象与制造它的外围对象之间就有了一种联系,所以它能访问其外围对象的所有成员,而不需要任何特殊条件。此外,内部类还拥有其外围类的所有元素的访问权。
interface Selector{
boolean end();
Object current();
void next();
}
public class Sequence {
private Object[] items;
private int next =0;
public Sequence(int size) {
items=new Object[size];
}
public void add(Object x) {
if (next<items.length) {
items[next++]=x;
}
}
public class SequenceSelector implements Selector{
private int i=0;
@Override
public Object current() {
return items[i];
}
@Override
public boolean end() {
return i==items.length;
}
@Override
public void next() {
if (i<items.length) {
i++;
}
}
}
public static void main(String[] args) {
Sequence sequence =new Sequence(10);
for (int i = 0; i < 10; i++) {
sequence.add(Integer.toString(i));
}
Selector selector =sequence.new SequenceSelector();
while(!selector.end()){
System.out.println(selector.current()+"");
selector.next();
}
}
}
其中:Selector selector =sequence.new SequenceSelector();
为创建内部类对象。
如果需要生成对外部类对象的引用,可以使用外部类的名字后面紧跟圆点和this。
public class DotThis {
void f(){System.out.println("DotThis.f()");}
public class Inner{
public DotThis outer() {
return DotThis.this;
}
}
public Inner inner() {
return new Inner();
}
public static void main(String[] args) {
DotThis dotThis =new DotThis();
DotThis.Inner dtInner =dotThis.inner();
dtInner.outer().f();
}
}
16. 匿名内部类注意事项:
如果定义一个匿名内部类,并且希望它使用一个在其外部定义的对象,那么编译器会要求其参数引用是finnal的,如果你忘记了,将会得到一个编译时错误信息。
17. 匿名内部类:
interface Contents{
int value();
}
public class Parcel7 {
public Contents contents() {
return new Contents() {
private int i =11;
public int value() {
return i;
}
};
}
public static void main(String[] args) {
Parcel7 parcel7 =new Parcel7();
Contents contents= parcel7.contents();
}
}
等价于:
package zengxiao;
interface Contents{
int value();
}
public class Parcel7 {
class MyContent implements Contents{
@Override
public int value() {
return 0;
}
};
public Contents contents() {
return new MyContent();
}
public static void main(String[] args) {
Parcel7 parcel7 =new Parcel7();
Contents contents= parcel7.contents();
}
}
18. 嵌套类:
普通内部类对象隐式地保存了一个引用,指向创建它的外围对象。
嵌套类意味着:
(1).要创建嵌套类的对象,并不需要其外围类的对象
(2).不能从嵌套类的对象中访问非静态的外围类对象。
如果想要创建某些公共代码,使得它们可以被某个接口的所有不同实现所共有,那么使用接口内部的嵌套类实现会显得很方便。
19. Map:
public class Statistics {
public static void main(String[] args) {
Random rand =new Random(47);
Map<Integer, Integer> map =new HashMap<Integer, Integer>();
for (int i = 0; i < 10000; i++) {
int r =rand.nextInt(20);
Integer freq =map.get(r);
map.put(r, freq==null?1:freq+1);
}
System.out.println(map);
}
}
20. Collection:
Stack
栈通常是指后进先出的容器(LIFO).
LinkedList具有能够直接实现栈的所有功能的方法。
import java.util.LinkedList;
public class Stack<T> {
private LinkedList<T> storage =new LinkedList<T>();
public void push(T v){storage.addFirst(v);}
public T peek() {
return storage.getFirst();
}
public T pop() {
return storage.removeFirst();
}
public Boolean empty() {
return storage.isEmpty();
}
public String toString() {
return storage.toString();
}
}
public class StackTest {
public static void main(String[] args) {
Stack<String> stack = new Stack<String>();
for (String s : "my dog has fleas".split(" ")) {
stack.push(s);
}
while (!stack.empty()) {
System.out.println(stack.pop()+"");
}
}
}
Set
不保存重复的元素。查找成为了set最重要的操作。,hashSet专门对快速查找进行了优化。如果想对结果进行排序的话建议使用TreeSet来代替HashSet
Queue
队列是一个典型的先进先出(FIFO)的容器。
21. 添加一组元素的方法:
Collections.addAll()和Arrays.asList()
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class zeng {
public static void main(String[] args) {
List<Integer> colList = new ArrayList<Integer>();
Integer[] moreInts = { 1, 2, 3, 4, 5 };
Collections.addAll(colList, moreInts);
for (Integer integer : moreInts) {
System.out.println(integer);
}
List<Integer> list = Arrays.asList(moreInts);
for (Integer integer : list) {
System.out.println(integer);
}
}
}
22. 类型信息和泛型:
在Java中,所有类型转换都是在运行时进行正确性检查的。这也是RTTI名字的含义:在运行时,识别一个对象的类型。
Class类一个方法:
forName(String className)
返回与带有给定字符串名的类或接口相关联的 Class 对象。
无论何时,只要你想在运行时使用类型信息,就必须首先获得对恰当的Class对象的引用。Class.forName()就是实现此功能的捷径,因为你不需要为了获得Class引用而持有该类型的对象。
Java还提供另一种方法来生成对Class对象引用,即使用类字面变量。如:A.class
这样做不仅更简单,而且更安全,因为它在编译时就会受到检查(因此不需要置于try语句块中)。并且它根除了对forName()方法的调用,所以也更高效。
关键字instanceof。它返回一个布尔值,告诉我们对戏那个是不是某个特定类型的实例。
java泛型的一个局限性:基本类型无法作为类型参数。
泛型方法使得该方法能够独立于类而产生变化。以下是一个基本的指导原则:无论何时,只要你能做到,你就应该尽量使用泛型方法,因为它可以使事情更加清楚明白。另外,对于一个static的方法而言,无法访问泛型类的类型参数,所以,如果static方法需要使用泛型能力,就必须使其成为泛型方法。