Java学习

-------------------------学习MLDN教学视频-------------------------

1、数据类型:
基本数据类型:
引用数据类型:类、接口、数组

2、Person one=null; //是声明一个对象
one=new Person(); //是实例化对象

3、要是没有实例化
会有异常 NullPointerException

4、实例化
实例化的是指在堆内存对类的属性进行赋值,而方法是在公共内存区中

5、封装性
体现在public与private等等。这样可以保护内容(比如有的属性要被保护),保证了类的完整性。
被封装的属性如果要被访问,则需要缩写setter及getter方法完成。setName getName

6、匿名构造方法
如果定义了有参数的构造方法,就不会自动生成没有参数的构造方法。

7、重载与构造方法重载
参数的个数or参数的类型不同

8、匿名对象
如果一个对象只使用一次,就可以将其定义成匿名对象。
所谓的匿名对象就是少了一个栈中的一个变量,只在堆中实例化了对象。

9、用==进行比较堆内存的中的内容
与栈中变量的比较不同,堆中的内容若是==,表示是指向同一个堆内存。而在栈中只表示他们的值相同,而不管是不是同一个内存空间。
比较他们之间的值是否相等,应该使用String.equals()

10、String两种赋值方式
直接赋值,可以节省内存,因为他是先看堆中看有没有这个字符串。但是用new String()根本不会管,直接开辟堆内存空间了。
所以建议用直接赋值。但是考虑到可能改变了,导致了另一个变量指向的堆的内容变了,但是因为String的对象是不可改变的,所以不用担心。所以不要经常链接-断开的方式,这样会造成很多的垃圾。所以用StringBuffer,这也是专门用来进行处理的。也就是说,如果字符串需要动态改变,就需要用 StringBuffer 类。

11、String常用的api
split()和replaceAll()常常结合正则表达式使用;toCharArray()将字符串变成字符数组;用String可将字符数组变成字符串;charAt()--to find the char of some index;indexOf()找打相应的String的index;trim();startsWith() & endsWith();equalsIgnore
Case()不区分大小写相等;

12、引用传递
类里面的字段可以是自己的本身的类型

13、this也可以用作构造方法中
使用this可以调用其他构造方法,但是此语句必须放在构造方法的首行。thid()、this(arg1)等等必须放在第一个

14、static
在调用static属性的时候,最好使用类名称直接调用。采用“类名称.属性”的形式调用。(static声明属性)
(static声明方法)也可以直接使用类名称调用

15、 java中有几个类型的内存区域
栈内存:可以保存对象的名称
堆内存:保存每个对象的具体属性
全局数据区:保存static类型的属性
全局代码区:保存所有方法的定义

16、内部类加上static就是外部类,可以直接在外部访问。

17、super关键字
先调用父类的构造方法,再调用子类的构造方法。对于子类的构造方法,隐含了一个“super”的语句。有时也将了父类成为超类。在子类构造方法的第一行加上super()是一样的。

18、覆写与super
子类中定义了与父类一样的方法。子类中复写的方法的访问权限不能小于父类中方法的访问权限。要是一定要用父类的方法,就用super关键字,这样就更加明确的说,要从父类中查找,就不从子类查找了。
父类中的方法的访问权限是private,子类中复写的方法的权限是default,这样是不能被复写的。
方法的覆写与重载。重载发生在一个类中,对权限没有要求。覆写放生的继承中,对权限有要求。
在构造方法中,this和super不能同时调用

19、final关键字
final类不能有子类;final方法不能子类被复写;final方法是常量,不可以被修改。

20、abstract
抽象方法只需声明不需实现;抽象类必须被继承,子类如果不是抽象类,必须覆写抽象类中的抽象方法。没有方法体,即是没有{}

21、接口interface
接口的是由全局常量和公共的抽象方法组成。全局常量+抽象方法
public static final
public abstract

22、多态性
方法的重载与覆写;对象的多态性
向上转型;向下转型
向上转型:自动完成。父类中没有的方法子类中有,就没用了。子类中覆写了的父类对象,还是子类的方法体。
向下转型:强制。发生向下转型关系之前必须先发生向上转型关系。子类中有的方法,就全部按照子类的方法。
注意:如果要想产生对象的向下转型,则肯定必须先产生一个向上的转型关系。

23、instanceof
instanceof用于判断一个对象是否是某个类的实例。在对象向下转型之前最好使用instanceof关键字进行验证。

24、注意:一个类永远不要去继承一个已经实现好的类。而只能继承抽象类或实现接口

25、工厂模式 代理设计模式 适配器设计模式
适配器设计,在java的图形界面设计上用得非常多。如果一个接口中的方法过多的话,不需要全部实现的话,就用适配器设计模式。但是在java EE设计中并不常见。

26、Object输出的是利用toString()方法输出的
Object是所有类的父类。只要是引用数据类型都可以用Object进行接受,包括数组。
toString()对象打印时调用,equals()对象比较时调用。

27、包装类 装箱、拆箱
把int包装成一个类,这样就可以以对象的形式操作一个对象了。将基本数据类型变为包装类成为装箱;将包装类的类型变为基本数据类型称为拆箱。
在JDK1.5之后,对与程序本身来说包装类是不能直接进行加减等操作的。但是在JDK1.5之后,可以直接进行加减操作,可以自动装箱、拆箱.甚至可以将字符串变成指定的数据类型。

28、包
包实际上就是一个文件夹。一个*.class文件要保存在一个文件夹之中。在java编译指令中,提供了打包编译命令,在编译的时候加上参数 编译一个文件:javac -d . *.class

29、一个*.class中往往只定义一个public class

30、多线程
继承Thread类;实现Rannable接口
继承Thread必须覆写run()方法;如果想真正启动一个线程,要用start()方法.一旦使用start(),实际上还是调用的run()方法.(run()方法跑起来的线程是一个一个顺序执行的,而start()是抢占式执行的。)
runnable()接口,只定义了一个run()方法。

31、范型是JAVA1.5之后出现的新特性
范型解决数据安全性问题。 [NOTE:范型可以理解为类型先不确定,用到的时候再确定]范型的本质是类型参数化。注意:在范型中,不能用Info<Object>来接受Info<String>类型。

32、java集合(java的类集)
Collection接口。对象数组中包含一组对象,但是对象数组使用的时候存在长度的限制,那么类集是专门解决这种限制的,使用类集可以方便的向数组中增加任意多个数据。
Colletion、List、Set、Map、Iterator、ListIterator、Enumeration、SortedSet、SortedMap、Queue、Map.Entry
重点:List、Set、SortedSet、Queue,全都集成Collection

33、java中一些重要的点
四个:OO、java类集、java IO、JDEC

34、List接口,ArrayList类
List接口要比Collection接口强大很多。添加的方法是用add()、addAll()方法,并且可以定义添加的位置,addAll()方法可以用来增加一个Collection实例化的对象。
删除用remove()方法;size()获得大小;get()获得第几个元素.
截取部分用subList();
LinkedList类,表示一个链表类

35、反射机制
可以通过对象反射求出类的名称。getClass()获得一个对象属于哪一个类.

36、Annotation
元数据特性,也成为注释。
@Override表示方法覆写的正确性;
@Deprecated本身是不建议使用的;
@SuppressWarnings压制警告信息

 

 

-------------------------学习vamei的Java教程以及可可西的博客-------------------------

1.包

如果包没有放在当前工作路径下,我们在使用包时,需要通知Java。比如,我们将包放在/home/vamei/javapackage中,这样Human.class位于/home/vamei/javapackage/com/vamei/society/Human.class,而我们的工作路径为/home/vamei。这样,包就无法被找到。一个方法是在使用javac和java时,用-classpath说明包所在的文件夹路径,比如:

$javac -classpath /home/vamei/javapackage:. TestAgain.java

$java -classpath /home/vamei/javapackage:. TestAgain

就是从/home/vamei/javapackage和工作路径(.)中寻找包。Java可以从/home/vamei/javapackage中可以找到Human类,从.中可以找到TestAgain类。

另外也可以设置系统的CLASSPATH环境变量,将上述路径加入到该变量中,而不用每次都键入-classpath选项。

 

2.方法覆盖(override)

Java中没有virtual关键字!要是参数不是完全一样的,那就是重载,不然就是覆盖。

 

3.JVM & .class文件

 .class文件可以在任意装有Java虚拟机(JVM, Java Virtual Machine)的平台上运行,这帮助我们克服了系统差异造成的程序移植困难。 
 
4.构造器
在创建衍生对象的时候,基类对象先被创建和初始化(刚刚结束的好大夫的笔试又TM错了)。
 
5.类数据&类方法
类方法,也就是声明为static的方法。类方法代表了类可以实现的动作,其中的操作不涉及某个具体对象。如果一个方法声明为static,那么它只能调用static的数据和方法,而不能调用非static的数据和方法。调用类方法时,我们可以通过class.method()的方式调用,也可以通过object.method()的方式调用。
 
6.final关键字
final关键字的基本含义是: 这个数据/方法/类不能被改变了。
final基本类型的数据: 定值 (constant value),只能赋值一次,不能再被修改;final方法: 该方法不能被覆盖。private的方法默认为final的方法;final类: 该类不能被继承。
 
7.jar文件(在jdk的安装文件里lib文件夹中就有.jar文件,我们将它加入CLASSPATH环境变量中)
JAR(Java Archive,Java 归档文件)是与平台无关的文件格式,它允许将许多文件组合成一个压缩格式。JAR文档格式以流行的 ZIP 文件格式为基础。与 ZIP 文件不同的是,JAR 文件不仅用于压缩和发布,而且还用于部署和封装库、组件和插件程序,并可被像编译器和 JVM 这样的工具直接使用。(来自百度)
 
8.抽象类&抽象方法
类中的方法可以声明为abstract。abstract method, abstract类
参数 抽象类 接口
默认的方法实现 它可以有默认的方法实现 接口完全是抽象的。它根本不存在方法的实现
实现 子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现。 子类使用关键字implements来实现接口。它需要提供接口中所有声明的方法的实现
构造器 抽象类可以有构造器 接口不能有构造器
与正常Java类的区别 除了你不能实例化抽象类之外,它和普通Java类没有任何区别 接口是完全不同的类型
访问修饰符 抽象方法可以有publicprotecteddefault这些修饰符 接口方法默认修饰符是public。你不可以使用其它修饰符。
main方法 抽象方法可以有main方法并且我们可以运行它 接口没有main方法,因此我们不能运行它。
多继承 抽象方法可以继承一个类和实现多个接口 接口只可以继承一个或多个其它接口
速度 它比接口速度要快 接口是稍微有点慢的,因为它需要时间去寻找在类中实现的方法。
添加新方法 如果你往抽象类中添加新的方法,你可以给它提供默认的实现。因此你不需要改变你现在的代码。 如果你往接口中添加方法,那么你必须改变实现该接口的类。

 
9.对象引用(reference)
Human aPerson = new Human(160);

a.首先看等号的右侧。new是在内存中为对象开辟空间。具体来说,new是在内存的堆(heap)上为对象开辟空间。这一空间中,保存有对象的数据和方法。b.再看等号的左侧。aPerson指代一个Human对象,被称为对象引用(reference)。实际上,aPerson并不是对象本身,而是类似于一个指向对象的指针。aPerson存在于内存的栈(stack)中。c.当我们用等号赋值时,是将右侧new在堆中创建对象的地址赋予给对象引用。(来自vamei)引用和对象分离;引用指向对象。

 
在 Java中,所有的(普通)对象都储存在堆上。因此,new关键字的完整含义是,在堆上创建对象。基本类型(primitive type)的对象,比如int, double,保存在栈上。所以在申明基本类型的时候不需要用new。基本类型变量的值传递不会影响到原变量引用类型变量的传递会影响到原变量
一个对象多个引用
 
10.Java文件的命名规则

源文件的命名规则:如 果在源程序中包含有公共类的定义,则该源文件名必须与该公共类的名字完全一致,字母的大小写都必须一样。这是java语言的一个严格的规定,如果不遵守, 在编译时就会出错。因此,在一个java源程序中至多只能有一个公共类的定义如果源程序中不包含公共类的定义,则该文件名可以任意取名。如果在一个源程 序中有多个类定义,则在编译时将为每个类生成一个.class文件。

 

11.Java中的异常

Java中的异常类都继承自Throwable类。一个Throwable类的对象都可以抛出(throw)。
 来自vamei的异常处理
橙色部分是unchecked异常(异常处理机制往往不处理这部分异常),而蓝色部分是checked异常

所有的异常类必须从Throwable派生,异常分为两大类:一类是unchecked异常(橙色部分):
1、Error类异常由JVM生成并抛出(如:动态链接错误),我们不能在编程层面上解决Error,所以应该直接退出程序。
2、RuntimeException(及其衍生类)是Java程序自身造成的,RuntimeException完全可以通过修正Java程序避免。这类异常,Java编译器不强制要求程序员对其捕获和处理。

另外一类就是checked异常(淡蓝色部分):
Java编译器要求程序员必须捕获或声明所有的这类非运行时异常(如:文件找不到造成的IOException)。

/******************* 自定义异常 *******************/
class ExceptionSelf1Base extends Exception
{
    private String m_strExpInfo;
    ExceptionSelf1Base(String strVal)
    {
        m_strExpInfo = strVal;
    }
    
    public String toString()
    {
        return "Exception: " + m_strExpInfo;
    }
}

class ExceptionSelf2Base extends Exception
{
    private int m_nExpInfo;
    ExceptionSelf2Base(int nVal)
    {
        m_nExpInfo = nVal;
    }
    
    public String toString()
    {
        return "Exception: " + m_nExpInfo;
    }
}

class ExceptionSelf1 extends ExceptionSelf1Base
{
    public ExceptionSelf1(String strVal)
    {
        super(strVal);
    }
}
/******************* 抛出异常 *******************/
class ExceptionTest
{
    // 需要通过throws关键字声明函数内的所有抛出的checked异常
    public void throwExp(int nMode) throws ExceptionSelf1,ExceptionSelf1Base,ExceptionSelf2Base
    {
        if (nMode < 0)
        {
            ExceptionSelf1Base e1 = new ExceptionSelf1Base("nMode < 0");
            throw e1;
        }
        else if (nMode < 100)
        {
            ExceptionSelf2Base e2 = new ExceptionSelf2Base(100);
            throw e2;
        }
        
        ExceptionSelf1 e = new ExceptionSelf1("nMode >= 100");
        throw e;
    }
}
/******************* 异常处理 *******************/
public class AppMain
{
    public static void main(String[] args) 
    {    
        ExceptionTest expTest = new ExceptionTest();
        try
        {
            expTest.throwExp(100);
        }
        // 捕捉异常时,需要按照特殊到一般的顺序进行捕捉
        catch (ExceptionSelf1 e)
        {
        }
        catch (ExceptionSelf1Base e)
        {
        }
        catch (ExceptionSelf2Base e)
        {    
        }
        catch (Exception e)
        {
        }
        // finally为非必需的块
        // 进入try块后,无论发生还是不发生异常,finally块中的代码都要被执行,提供了统一的出口
        finally
        {      
        }
    }
}

  

 
12.装饰器
BufferedReader br =
              new BufferedReader(new FileReader("file.txt")); 

            String line = br.readLine();

            while (line != null) {
                System.out.println(line);
                line = br.readLine();
            }
            br.close();

  打开一个文件的操作。BufferedReader()是一个装饰器(decorator)它接收一个原始的对象,并返回一个经过装饰的、功能更复杂的对象

 

13.RTTI

运行时类型识别(RTTI, Run-Time Type Identification)机制。

 

14.多线程

在JVM的一个进程空间中,一个栈(stack)代表了方法调用的次序。对于多线程来说,进程空间中需要有多个栈,以记录不同线程的调用次序。多个栈互不影响,但所有的线程将共享堆(heap)中的对象。

 

15.Java容器

 

16.嵌套类
直接创建内部类对象时,必须是基于一个外部类对象。也就是说,内部类对象必须依附于某个外部类对象。与此同时,内部类对象可以访问它所依附的外部类对象的成员(即使是private的成员)。
在类的内部定义static类。这样的类称为嵌套static类(nested static class)。我们可以直接创建嵌套static类的对象,而不需要依附于外部类的某个对象
 
17.Java的MVC模型
目前,J2EE的各种框架层出不穷,但各种框架的核心技术依然是J2EE三项基础技术:JSP、javascript、Servlet,而开源框架还是Struts+Spring+Hibernate的天下。
 
18.@的应用

Java annotation/Java标注
语法: @关键字(值)
用于把关键字和值传递给编译器,更精确低控制编译器的动作。
关键字都是随技术、框架、编译器的不同而不同,含义也不同、数量不定。可以由子技术或开发者扩充。
比如@override 说明会重写该方法

import play.data.validation.Constraints.Email;
import play.data.validation.Constraints.Required;

public class User {
    @Email
    public String email;
    @Required
    public String password;
    public String comment;
}

  @Email的限定就要求输入为"*@*"的形式。@Required则要求输入栏不为空。如果违反这些限定,那么Play将抛出异常。

 

19.Java的容器

数组,list,set,map

 

20.java中的值引用

Java函数参数没有指针传递、引用传递,只有值传递。

值类型参数会产生一个值类型副本,引用类型参数会产生一个引用类型副本(注意:引用类型间赋值不会产生新的对象,因此不会触发拷贝构造函数调用)

因此,想通过函数来实现两个数值变量或对象的交换是不行的

要是想实现两个值通过函数进行交换,通过函数来实现两个数值变量对象的交换也是有办法的(包裹:将要交换的数值变量或对象包裹到一个数组或类中)。

/***** AppMain.java *****/
public class AppMain 
{
    public static void swapIntTrue(int[] a, int[] b)
    {
        int c = a[0];
        a[0] = b[0];
        b[0] = c;
    }
    
    public static void swapIntegerTrue(Integer[] oa, Integer[] ob)
    {
        Integer oc = oa[0];
        oa[0] = ob[0];
        ob[0] = oc;
    }
    
    public static void main(String[] args) 
    {
        int n1 = 0;
        int n2 = 1;
        Integer on1 = new Integer(0);
        Integer on2 = new Integer(1);
        
        int nArray1[] = new int[1];
        int nArray2[] = new int[1];
        nArray1[0] = n1;
        nArray2[0] = n2;
        System.out.println("n1="+n1 + ", n2="+n2);//n1=0, n2=1
        swapIntTrue(nArray1, nArray2);
        n1 = nArray1[0];
        n2 = nArray2[0];
        System.out.println("n1="+n1 + ", n2="+n2);//n1=1, n2=0
        
        Integer onArray1[] = new Integer[1];
        Integer onArray2[] = new Integer[1];
        onArray1[0] = on1;
        onArray2[0] = on2;
        System.out.println("on1="+on1 + ", on2="+on2);//on1=0, on2=1
        swapIntegerTrue(onArray1, onArray2);
        on1 = onArray1[0];
        on2 = onArray2[0];
        System.out.println("on1="+on1 + ", on2="+on2);//on1=1, on2=0
    }
}

  

21.java的装箱拆箱

java里面有自动装箱和拆装的概念,是对基本数据类型和其封装类的相互转换的描述。
当基本类型的数据向其封装类转换时,称为自动装箱。反之,称为拆装。下面给你一个例子:

Integer a = new Integer(1);
a = a + 1;//自动装箱

int 型的1 竟然可以直接和Integer对象相加?   关于int和integer之间的关系

其实,这就是JVM“自动”先将Integer型的a转化为int型,就是自动拆装

然后,将两个int型号的数据相加
然后装值给转换为Integer的对象,这个就是自动装箱
JAVA从JDK1.5后,开始支持这个特性

 

22.java中冒号的用法

首先,可以用在三元运算(比如  (a>b)?true:false);

其次,在循环中用来标识跳到哪儿

C1:for(int i=0; i<100; i++)
    {
        C2:for(int j=0; j<100; j++)
        {
            if (i==50 && j==80)
            {
                // 继续C1层循环
                continue C1;
            }
        }
    }

再次,可以用作遍历

int[] code = {0,1,2,3,4,5};
// 针对数组、集合、枚举的for循环形式   JDK1.5之后增加
for (int e : code)
    {
    }

最后,switch case中可以用

 

23.java中的StringBuffer和StringBulider

StringBuffer   处理可变字符串(线程安全),不可被继承(final)

StringBuilder  处理可变字符串(线程不安全,拥有更高的性能),不可被继承(final),JDK1.5引入

StringBuffer与StringBuilder在使用上几乎没有区别

StringBuffer sb1 = new StringBuffer("Hello ");
sb1.append("World!");
String str1 = sb1.toString(); // Hello World!

StringBuilder sb2 = new StringBuilder("Hello ");
sb2.append("World!");
String str2 = sb2.toString(); // Hello World!

  

24.范型

泛型从JDK1.5才引进;经常被称为参数化类型,它能够像方法一样接受不同类型的参数。

泛型中的通配符:
(1) 泛型中可以使用"?"通配符作为参数,表示该泛型可以接受任意类型的数据
(2) 上届通配符:只允许类A或类A的子类作为参数传入;表示方式:泛型类型<? extends A>
(3) 下届通配符:只允许类A或类A的父类作为参数传入;表示方式:泛型类型<? super A>

如果想从一个数据类型里获取数据,使用 ? extends A 通配符
如果想把对象写入一个数据结构里,使用 ? super A 通配符
如果既想存又想取,那就不要用通配符

复制代码
/***** AppMain.java *****/
import java.util.*;
public class AppMain 
{
    public static void main(String[] args) 
    {
        //ArrayList<?> gList1 = new ArrayList<?>();//编译错误,通配符修饰的泛型不能用来直接创建对象
        ArrayList<String> gStrList2 = new ArrayList<String>();
        gStrList2.add("1");
        ArrayList<?> gList2 = gStrList2;
        Object objVal = gList2.get(0); //通配符修饰的泛型可以读取数据到Object类型
        //gList2.add("2"); //编译错误,【?】通配符修饰的泛型不能写入任何类型数据
        
        //ArrayList<? extends Number> geList1 = new ArrayList<? extends Number>();//编译错误,通配符修饰的泛型不能用来直接创建对象
        ArrayList<Integer> geIntList2 = new ArrayList<Integer>();
        geIntList2.add(1);
        List<? extends Number> geList2 = geIntList2;
        Object objVa2 = geList2.get(0); //通配符修饰的泛型可以读取数据到Object类型
        Number nVal = geList2.get(0); //【上届通配符】修饰的泛型可以读取数据到Number类型
        //geList2.add(new Integer(2)); //编译错误,【上届通配符】修饰的泛型不能写入任何类型数据
        
        //ArrayList<? super Integer> gsList1 = new ArrayList<? super Integer>();//编译错误,通配符修饰的泛型不能用来直接创建对象
        ArrayList<Integer> gsIntList2 = new ArrayList<Integer>();
        gsIntList2.add(1);
        List<? super Integer> gsList2 = gsIntList2;
        Object objVal3 = gsList2.get(0); //通配符修饰的泛型可以读取数据到Object类型
        //Integer nVal2 = gsList2.get(0); //编译错误,【下届通配符】修饰的泛型不能读取数据到除Object类型中
        gsList2.add(2); //【下届通配符】修饰的泛型可以写入Integer及其父类类型数据
        
        /*** 自定义泛型 ***/
        //Gencs<CString,String,String> gen1 = new Gencs<Float,String,String>();//编译错误,参数1必须为Number或其子类
        Gencs<Integer,String,String> gen2 = new Gencs<Integer,String,String>();
        Gencs<Float,String,String> gen3 = new Gencs<Float,String,String>();
        gen3.setX(3.0f);
        Float fGen3 = gen3.getX();
        Object oGen3 = gen3.getX();
        //Integer iGen3 = gen3.getX();//编译错误,返回值为Float类型
        //gen3.setX(3);//编译错误,必须传入Float类型参数
    }
}

class Gencs<X extends Number, Y, Z> 
{
    private X m_x;    
    //static Y m_y; //编译错误,不能用在静态变量中    
    public X getX() 
    {    
        return m_x;    
    }
    
    public void setX(X x)
    {
        m_x = x;
    }
    public void fun() 
    {        
        //Z z = new Z();//编译错误,不能创建对象    
    }
}
复制代码

 

25.集合

注:点框的为接口、虚线框的为抽象类、实线框的为功能类(右下角的Collections为公用工具类,里面含有大量静态成员函数供集合使用)

集合只能容纳对象,不能容纳基本数据类型;元素通过实现Comparable接口、或提供一个实现Comparator接口的比较算法类来定义比较的规则。

List集合是有序集合(放入的顺序与存储的顺序一致),集合中的元素可以重复,访问集合中的元素可以根据元素的索引来访问。
Set集合是无序集合(放入的顺序与存储的顺序不一致),集合中的元素不可以重复,访问集合中的元素只能根据元素本身来访问。
Map集合中保存key-value对形式的元素,其key对象是不允许重复的(换个角度说:key对象的合集就是一个Set集合),访问时只能根据每项元素的key来访问其value;插入时如果key存在,则替换原来的value对象。

对象重复的含义:
(1) 两个对象e1和e2,如果e1.equals(e2)为true,则认为e1和e2重复,否则认为两个对象不重复
(2) 默认两个对象是否相等的equals方法是判断两个对象变量引用值是否指向同一个地址空间,我们可以重写equals方法来自定义重复的含义

ArrayList线程不安全;Vector线程安全(如果是单线程程序,推荐使用ArrayList)
ArrayList通过数组实现,LinkedList通过链表实现(不涉及到插入、删除等操作,推荐使用ArrayList)
HashSet相比,TreeSet会对容器内的元素进行排序;同理,相比HashMapTreeMap也会对容器内的元素进行排序
HashMap线程不安全,键与值都可以为null;Hashtable线程安全,键与值不能为null(如果是单线程程序,推荐使用HashMap)

复制代码
/***** AppMain.java *****/
import java.util.*;
public class AppMain 
{
    public static void main(String[] args) 
    {
        /* ArrayList */
        List list = new ArrayList();
        list.add(new Integer(1));
        list.add("2");
        list.add(new Short((short)3));
        ListIterator iList = list.listIterator();
        while(iList.hasNext())
        {
            System.out.println(iList.next());
        }
        
        /* HashSet */
        Set hSet = new HashSet();
        hSet.add("1");
        hSet.add(new Integer(2));
        hSet.add("3");
        Iterator iHSet = hSet.iterator();
        while(iHSet.hasNext())
        {
            System.out.println(iHSet.next());
        }
        
        /* TreeSet */
        Set tSet = new TreeSet();
        tSet.add("1");
        //tSet.add(new Integer(2)); //运行时错误,TreeSet会对元素进行排序,因此需要实现插入元素间相互比较的Comparable接口
        tSet.add("3");
        Iterator iTSet = tSet.iterator();
        while(iTSet.hasNext())
        {
            System.out.println(iTSet.next());
        }
        
        /* HashMap */
        HashMap hm = new HashMap();
        hm.put(null, 0);
        hm.put("1", null);
        hm.put(new Integer(2), "2");
        hm.put("3", new Float(3.0f));
        Set sHm = hm.keySet();
        Iterator iHm = sHm.iterator();
        while(iHm.hasNext())
        {
            Object k = iHm.next();
            Object v = hm.get(k);
            System.out.println(k + "=" + v);
        }
        
        /* Hashtable */
        Hashtable ht = new Hashtable();
        // ht.put(null, 0);  //运行时错误
        // ht.put("1", null); //运行时错误
        ht.put(new Integer(2), "2");
        ht.put("3", new Float(3.0f));
        Enumeration e = ht.keys();
        while(e.hasMoreElements())
        {
            Object k = e.nextElement();
            Object v = ht.get(k);
            System.out.println(k + "=" + v);
        }
        
        /* TreeMap */
        TreeMap tm = new TreeMap();
        tm.put("1", new Long(1));
        tm.put("2", new Double(2.0));
        // tm.put(new Integer(3), "3");  //运行时错误,TreeMap会按照Key进行排序,因此Key需要实现插入元素间相互比较的Comparable接口
        Set sTm = tm.keySet();
        Iterator iTm = sTm.iterator();
        while(iTm.hasNext())
        {
            Object k = iTm.next();
            Object v = tm.get(k);
            System.out.println(k + "=" + v);
        }
    }
} 
复制代码

以上的示例为非泛型实现的集合,现在已不推荐使用了。(由于使用集合中的元素时,必须进行造型操作,效率低;而且造型操作可能在程序运行时出现问题)

泛型实现的集合在定义容器时,同时定义容器中对象的类型,这就使得容器内的元素只能是该对象类型或其子对象类型。

泛型实现的集合拥有与非泛型实现的集合同样的特性,一致的外部接口。(ArrayList  LinkedList  HashSet  TreeSet  HashMap  TreeMap  Hashtable

复制代码
/***** AppMain.java *****/
import java.util.*;
public class AppMain 
{
    public static void main(String[] args) 
    {
        /* ArrayList */
        List<String> list = new ArrayList<String>();
        list.add("1");
        list.add("2");
        list.add("3");
        ListIterator<String> iList = list.listIterator();
        while(iList.hasNext())
        {
            System.out.println(iList.next());
        }
        
        /* HashSet */
        Set<Integer> hSet = new HashSet<Integer>();
        hSet.add(1);
        hSet.add(new Integer(2));
        hSet.add(new Integer(3));
        Iterator<Integer> iHSet = hSet.iterator();
        while(iHSet.hasNext())
        {
            System.out.println(iHSet.next());
        }
        
        /* TreeSet */
        Set<String> tSet = new TreeSet<String>();
        tSet.add("1");
        //tSet.add(new Integer(2)); //编译时错误
        tSet.add("3");
        Iterator<String> iTSet = tSet.iterator();
        while(iTSet.hasNext())
        {
            System.out.println(iTSet.next());
        }
        
        /* HashMap */
        HashMap<String, Integer> hm = new HashMap<String, Integer>();
        hm.put(null, 0);
        hm.put("1", null);
        hm.put("2", new Integer(2));
        hm.put("3", new Integer(3));
        Set<String> sHm = hm.keySet();
        Iterator<String> iHm = sHm.iterator();
        while(iHm.hasNext())
        {
            String k = iHm.next();
            Integer v = hm.get(k);
            System.out.println(k + "=" + v);
        }
        
        /* Hashtable */
        Hashtable<String, Integer> ht = new Hashtable<String, Integer>();
        //ht.put(null, 0);  //运行时错误
        //ht.put("1", null); //运行时错误
        ht.put("2", new Integer(2));
        ht.put("3", 3);
        Enumeration<String> e = ht.keys();
        while(e.hasMoreElements())
        {
            String k = e.nextElement();
            Integer v = ht.get(k);
            System.out.println(k + "=" + v);
        }
        
        /* TreeMap */
        TreeMap<String, Integer> tm = new TreeMap<String, Integer>();
        tm.put("1", 1);
        tm.put("2", new Integer(2));
        // tm.put(new Integer(3), 3);  //编译时错误
        Set<String> sTm = tm.keySet();
        Iterator<String> iTm = sTm.iterator();
        while(iTm.hasNext())
        {
            String k = iTm.next();
            Integer v = tm.get(k);
            System.out.println(k + "=" + v);
        }
    }
}
复制代码

 

26.组合继承

组合的关系是“has a”,比如手电筒has a电池

 

上面很多来自博客

posted @ 2014-12-02 19:13  陈不二  阅读(251)  评论(0编辑  收藏  举报
yes, javascript 拯救世界