您的位置:首页 > 编程语言 > Java开发

JAVA学习笔记(持续更新...)

2016-11-30 22:45 567 查看
11/28/2016 7:27:23 PM 集合类

Collection接口是List、Set、Queue接口的父接口

Collection接口定义了可用于操作List、Set和Queue的方法–增删改查

List接口及其实现类–ArrayList

List是元素有序并且可以重复的集合,被称为序列。

List可以精确的控制每个元素的插入位置,或删除某个位置元素

List有add()插入方法和get()获取方法

ArrayList–数组序列,是List的一个重要实现类

ArrayList底层是由数组实现的,这也是其名字的由来

以下三种方法都是用来取出List中元素的方法:

—–for循环—–

public void testGet(){
int size=coursesToSelect.size();
for(int i=0;i<size;i++){
Course cr=(Course) coursesToSelect.get(i);
System.out.println("取出的课程:"+cr.getId()+":"+cr.getName());
}
}


—–迭代器—–

Iterator是一个接口,依赖于集合存在的

Iterator it=courseToSelect.iterator();
while(it.hasNext()){
Course cr=(Course) it.next();
System.out.println("课程:" + cr.id + ":" + cr.name);
}


—–for each(增强for循环)—–

凡是继承了Iterable接口的类所生成的对象都可以用for/each循环

for(Object obj:coursesToSelect){//遍历集合中的每一个元素,作为每一个Object变量
Course cr=(Course) obj;
System.out.println("课程:" + cr.id + ":" + cr.name);
}


Course是信息课程类,有id和name属性。courseToSelect是list的序列容器对象。

1.remove(index);删除位置要大于0并且小于List(序列容器)的长度。如果要删除全部可以用for循环嵌套此方法。

2.remove(object);先要获得删除的值,用法是先定义一个信息变量通过get()来存放要删除的值,然后用remove(删除的对象值);

public void textdelect{
Course cr=(Course)(courseToSelect.get(4));
courseToSelect.remove(cr);//通过remove(对象值);


或者

courseToSelect.remove(4);//通过remove(删除位置);  }


3.removeAll(Arrays.asList());要删除指定的多个位置 Arrays.asLIst(对象数组名);作用是把数组转换为集合

用法是先创建信息对象数组存放删除元素的值,然后再用removeAll(Arrays.asList(对象数组名))方法,删除集合数组的元素。

public void textdelext2{
Course []course={(Course)(courseToSelect.get(4)),(Course)(courseToSelect.get(5))};  // 定义数组存放要删除的值
courseToSelect.removeAll(Arrays.asList(course));  // 删除4和5位置的值  }


泛型<>;

规定List定义的容器只能存储某种类型的元素。不用泛型的话是什么类型的元素都可以插入,因为插入集合是忽略其类型,把它看成为Object类型,取出时需要强行转换对应的类型。

编写带有泛型的集合

List

注意了这里关于使用 Set 集的 hashCode的方法,hashCode方法的工作原理是Set.contains(E e)的时候,先调用从Object继承而来的hashCode方法,然后在调用equals()方法,连个方法都返回真的时候,才认定Set包含某个元素。

jvm运行时,给每个对象分配唯一一个标志身份的标志hanshcode。众类鼻祖Object的hashCode()方法在默认情况下,判断哈希码是不是相同.即如同equals默认情况下比较的是二者是不是同一个内存快。

Set集的contains方法,内部就是先调用hashCode再调用equals()方法。

很多情况要结合实际对hashCode进行改写。

11/29/2016 7:30:33 PM

List接口

- indexOf()方法:

原理为:循环遍历List集合中的每一个元素,并调用equals方法,判断传递的对象是否与集合中的对象相等,如果相等,返回该对象的索引位置(注:如何集合中有两个值相同的元素,则返回第一个得到的索引)

Map

通过containsKey()方法和containsValue()方法来判断键和值是否存在.

Map 中对对象进行了 Key 标记,通过 get(Key)可以取得对应的对象

Map 的containsValue()方法的参数是 Object 对象,因为Map 的 Value 值是对象元素

Map 的containsKey()方法取得 Map 映射的 Key 值

List中的contains()方法借Map中的containsValue()方法调用equals()方法来进行比较。所以要重写Hashcode和equals方法

跟 List 的 contains()方法一样,Map 中的 containsValue()方法也会调用每个 Value 值的 equals()方法去和参数对象比较

练习题的生成10以内随机长度字符串的实现例子:

public static String getRandomString() {
String base = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";//比较顺序
Random random = new Random();
Math.random();//Math.random()内部调用Random.nextDouble();
StringBuffer sb = new StringBuffer();
int strLen = random.nextInt(10);
int num;
for (int i = 0; i < strLen; i++) {
num = random.nextInt(base.length());
sb.append(base.charAt(num));
}
return sb.toString();
}


collection.sort()方法对元素进行排序,列表中的元素都必需实现 Comparable 接口,否则不能使用 sort()方法排序

11/30/2016 7:39:46 PM

1、栈

由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。


2、堆

由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,程序会一直占用内存,导致内存泄漏,在程序结束后,操作系统会自动回收。


3、自由存储区

由malloc等分配的内存块,它和堆是十分相似的,不过它是用free来释放分配的内存。


4、全局/静态存储区

全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。


5、常量存储区

这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改)。


Java的内存分配

Java程序运行时的内存结构分成:方法区、栈内存、堆内存、本地方法栈几种。

方法区存放装载的类数据信息,包括:

基本信息:每个类的全限定名、每个类的直接超类的全限定名、该类是类还是接口、该类型的访问修饰符、直接超接口的全限定名的有序列表。

·-每个已装载类的详细信息:运行时常量池、字段信息、方法信息、静态变量、到类classloader的引用、到类class的引用。

- 栈内存

Java栈内存由局部变量区、操作数栈、帧数据区组成,以帧的形式存放本地方法的调用状态(包括方法调用的参数、局部变量、中间结果……)。

- 堆内存

堆内存用来存放由new创建的对象和数组。在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。

- 本地方法栈内存

Java通过Java本地接口JNI(Java Native Interface)来调用其它语言编写的程序,在Java里面用native修饰符来描述一个方法是本地方法。

- String的内存分配

String是一个特殊的包装类数据,由于String类的值不可变性,当String变量需要经常变换其值时,应该考虑使用StringBuffer或StringBuilder类,以提高程序效率。

static

1. 静态方法中可以直接调用同类中的静态成员,但不能直接调用非静态成员.如果希望在静态方法中调用非静态变量,可以通过创建类的对象,然后通过对象来访问非静态变量

2. 在普通成员方法中,则可以直接访问同类的非静态变量和静态变量

3. 静态方法中可以直接调用静态方法,但不能直接调用非静态方法,需要通过对象来访问非静态方法

4. 注意main函数是一个静态函数

5. 创建对象时,系统的执行顺序: 静态初始化块——–普通初始化块——–构造方法

6. 静态初始化块只在类加载时执行,且只会执行一次

7. 静态初始化块只能给静态变量赋值,不能初始化普通的成员变量。(普通代码块可以为静态成员和非静态成员赋值)

封装

将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。

好处:
1、只能通过规定的方法访问数据。
2、隐藏类的实例细节,方便修改和实现

封装的步骤:
1、修改属性的可见性,设为private
2、创建个getter/setter方法用于属性的读写
3、在getter/setter方法中加入属性控制语句,对属性值的合法性进行判断


1.包的作用:

管理java文件
解决同名文件冲突


2.定义包:package包名

注:必须放在java源程序的第一行

包名间可以使用”.”号隔开

eg:com.imooc.MyClass


3.系统中的包

java.(功能).(类)
java.lang.(类)包含
d5a3
java语言基础的类
java.util.(类)包含java语言中各类工具类
java.io.(类)包含输入、输出相关功能的类


4.包的使用

1. 可以使用import关键字,在某个文件使用其他文件中的类。
`import com.imooc.music.MyClass`
2. java中,包的命名规范是全小写字母拼写
3. 使用的时候不但可以加载某个包下的所有文件
` eg:com.imooc.*`
也可以加载某个具体子包下的所有文件
` eg:com.imooc.music.*`


访问修饰符

private—-同类

默认——-同类—-同包

protecte–同类—-同包—子类

public—–同类—-同包—子类—其他

this (多见于get()、set()函数)

this关键字代表当前对象

this.属性 操作当前对象的属性

this.方法 调用当前对象的方法

内部类

为什么要使用内部类?

在《Think in java》中有这样一句话:

使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。

在我们程序设计中有时候会存在一些使用接口很难解决的问题,这个时候我们可以利用内部类提供的、可以继承多个具体的或者抽象的类的能力来解决这些程序设计问题。可以这样说,接口只是解决了部分问题,而内部类使得多重继承的解决方案变得更加完整。

其实使用内部类最大的优点就在于它能够非常好的解决多重继承的问题,但是如果我们不需要解决多重继承问题,那么我们自然可以使用其他的编码方式,但是使用内部类还能够为我们带来如下特性(摘自《Think in java》):

1、内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立。
2、在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类。
3、创建内部类对象的时刻并不依赖于外围类对象的创建。
4、内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。
5、内部类提供了更好的封装,除了该外围类,其他类都不能访问。


成员内部类

成员内部类用法注意:

1. 内部类访问外部类的属性、方法:

内部类可以直接访问外部类属性、方法,如重名,必须通过
外部类名.this.数据
来访问。

2. 外部类访问内部类的属性、方法:

外部类不能直接访问内部类属性、方法,必须先创建内部类对象,然后通过对象来访问。

3. 创建内部类对象:

外部类或其余内部类创建内部类对象:直接new

其余类创建内部类对象:必须使用外部类对象来创建内部类对象,而不能直接去 new 一个内部类对象,即:
内部类 对象名 = 外部类对象.new 内部类( )


方法内部类

-方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内可以使用。
-由于方法内部类不能在外部类的方法以外的地方使用,因此方法内部类不能使用访问控制符和 static 修饰符。


继承

1. 继承是类的一种关系,是一种“is a”的关系(Java中中只存在单继承)

2. 继承的好处:子类拥有父类的属性和方法、代码的复用

3. 语法:
class 子类 extends 父类{……}


private----不可以继承
protecte(待确认)


继承的初始化顺序:

1.初始化父类再初始化子类。

2.先执行初始化对象中的属性,再执行构造方法中的初始化。

父类对象–>属性初始化—>构造方法

子类对象–>属性初始化—>构造方法



Super关键字

super关键字的应用:

1.子类的构造过程中必须调用其父类的构造方法

2.如果子类的构造方法没有显示调用父类的构造方法,则系统会默认调用父类的无参构造方法。

3.如果显示的调用构造方法,必须在子类的构造方法的第一行,super()。

4.如果子类的构造方法中既没有显示调用父类的构造方法,父类又没有无参的构造方法,则编译就会报错

重写&&c重载

重写方法的规则:

参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载。

返回的类型必须一直与被重写的方法的返回类型相同,否则不能称其为重写而是重载。如果在子类中写了一个只有返回类型不同的函数,将不是重写,且会报错

访问修饰符的限制一定要大于被重写方法的访问修饰符
(public>protected>default>private)


重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常。例如:

父类的一个方法申明了一个检查异常IOException,在重写这个方法是就不能抛出Exception,只能抛出IOException的子类异常,可以抛出非检查异常。

而重载的规则:

必须具有不同的参数列表;

可以有不责骂的返回类型,只要参数列表不同就可以了;

可以有不同的访问修饰符;

可以抛出不同的异常;

final

final关键字: 表示“最终的”,即不可修改。

final可以修饰类、方法、属性和变量

1、修饰类:不允许被继承

2、修饰方法:不允许被重写

3、修饰属性:则该属性不会进行隐式初始化(不会自动初始化),需要手动初始化或者在构造方法中初始化 (但二者只能选一,即只能初始化一次后便不能更改)

4、修饰变量,只能在声明的时候赋一次值,成为常量。 (static final 会使其成为全局常量)



Object类

Object类是所有类的父类,如果一个类没有使用extends关键字明确标识继承另外一个类,那么这个类默认继承Object类,且Object类中的方法适合所有子类

toString()方法

在Object类里面定义toString()方法的时候返回的对象的哈希code码(对象地址字符串[唯一标识])

如果我们在代码里面直接输出一个对象,会输出这个对象在内存中的地址,我们把它称为哈希码,哈希码是通过哈希算法生成的一个字符串用来唯一区分对象的

可以通过重写toString()方法表示出对象的属性

(我们经常在输出对象的时候希望得到子类的属性值,那么我们就要重写从父类继承来的toString()方法,eclipse中右键菜单栏-源码source-生成generate toString(),他就会根据我们对象的属性帮我们生成一个toString()方法来输出属性值)

getClass()可以得到一个类对象,当我们new的时候得到的是一个类的对象如果对象调用getClass()方法我们得到的是类对象,类对象描述的是类的代码信息(类的代码信息:这个类有哪些属性\它是什么类型\变量名是什么\它有哪些方法\方法名是什么\方法里面的代码是什么;而类的对象关注的是对象的属性值的信息或者说这个对象的数据信息)

equals()返回值是布尔类型

比较的是对象的引用是否指向同一块内存地址——-对象实例化时,即给对象分配内存空间

使用方法如:dog.equals(dog2);

如果是两个对象,但想判断两个对象的属性是否相同,则重写equals()方法

地址是否相同—-if (this == obj)

对象是否为空—-if (obj == null)

getClass()可以得到类对象,判断类型是否一样—–if (getClass() != obj.getClass())

new出来的是类的对象,关注的是类的属性的具体的数据;

类对象是类的代码信息,关注的是类有什么属性和方法

4.属性值是否一样—-if (age != other.age)

代码参考

@Override
public boolean equals(Object obj){
//如果obj与比较对象的位置相同,说明obj是从集合中取出再与该位置的元素比较,所以肯定相同
if(this==obj)
return true;
if(obj==null){//若字符串为空,则不能进行字符串比较,所以返回false
return false;
if(!(obj instanceof Course)){//若果obj当前类型不是Course,则当前两个对象肯定不相同
//instanceof 它的作用是判断其左边对象是否为其右边类的实例
return false;
//若上述均通过,则说明obj为Course对象,且当前对象不为空
Course course=(Course)obj;
if(this.name==null){
if(course.name==null)
return true;
else
return false;
}else{
if(this.name.equals(course.name))
return true;
else
return false;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java