系列文章目录
一:上手
二:类和对象
三:primitive主数据类型和引用
四:方法操作实例变量
五:编写程序
六:继承、接口与多态
七:构造器与垃圾收集器
八:数字与静态
九:异常处理
十:集合与泛型
前言
行百里者半九十
1、集合
Java使用集合来组织和管理对象,因此集合类也成为容器类
从Collection的API说明中,我们发现3个主要的接口:List、Set、和Map
- List是一种知道索引位置的集合,是对付顺序的好帮手
- Set是不允许重复的集合,注重独一无二的性质
- Map使用成对的键值和数据值,是使用Key来搜索的专家
Java的集合类结构如图所示
HashSet
对象要怎样才算相等?
这里面包括引用相等性和对象相等性
引用相等性是堆上同一对象的两个引用,可以用==
来比较
对象相等性是指堆上两个不同对象在意义上是相同的,用equals()
来判断
hashCode()与equals()的相关规定
- 如果两个对象是相等的,则hashcode必须也是相等的
- 如果两个对象相等,则其中一个对象调用equals()必须返回true。也就是说,
a.equals(b)
则b.equals(a)
- 如果两个对象有相同的hashcode值,他们也不一定是相等的。但两个对象相等,则一定有相同的hashcode值
- 若equals被覆盖过,则hashcode也被覆盖过
- hashCode()的默认行为是对在heap上的对象产生独特的值。如果没有override过hashcode,则class的 两个对象怎么样都不会被认为是相同的
- equals()的默认行为是执行==的比较。也就是说会去测试两个引用是否对上heap上的同一个对象。如果equals()没有被覆盖过,则两对象不会被认为相同的,因为不同的对象有不同的字节组合
2、泛型
关于泛型,有三件重要的事
- 创建被泛型化类(例如ArrayList)的实例
new ArrayList<Song>()
- 声明与指定泛型类型的对象
List<Song> songList = new ArrayList<Song>()
- 声明(与调用)取用泛型类型的方法
void foo(List<Song> list)
x.foo(songList)
使用泛型的类
ArrayList是最常用的泛型化类型,有两个关键部分:
1、类的声明
2、新增元素的方法的声明
public class ArrayList<E> extends AbstractList<E> implements List<E> ... {
public boolean add(E o) {
//这里最重要!E用来指示可以加入ArrayList的元素类型
}
}
E是指类型参数,把E想做是“集合所要维护和返回的元素类型”
运用泛型的方法
泛型的类代表类的声明用到类型参数。泛型的方法代表方法的声明特征用到参数类型
1、使用定义在类声明的类型参数
public class ArrayList<E> extends AbstractList<E> implements List<E> ... {
public boolean add(E o) {
//这里最重要!E用来指示可以加入ArrayList的元素类型
}
}
2、使用未定义在类声明的类型参数
public <T extends Animal> void takeThing(ArrayList<T> list)
居然提醒我不是原创,我不甘心。。。。加上一段程序吧。
这段代码也使用的异常处理,也使用了泛型和集合,可以作为后续的回顾。
import java.util.*;
import java.io.*;
public class Jukebox1 {
ArrayList<Song> songList = new ArrayList<Song>();//歌曲名会存在String的ArrayList上
public static void main(String[] args) {
new Jukebox1().go();
}
class ArtistCompare implements Comparator<Song> {
public int compare (Song one, Song two) {
return one.getArtist().compareTo(two.getArtist());
}
}
//载入文件并列出内容
public void go() {
getSongs();
System.out.println(songList);
System.out.println("====按顺序输出====");
Collections.sort(songList);
System.out.println(songList);
ArtistCompare artistCompare = new ArtistCompare();
Collections.sort(songList, artistCompare);
System.out.println(songList);
HashSet<Song> songSet = new HashSet<Song>();
songSet.addAll(songList);
System.out.println(songSet);
}
//读取文件的程序
void getSongs() {
try {
File file = new File("SongList.txt");
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = null;
while ((line = reader.readLine()) != null) {
addSong(line);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
//添加歌曲的程序
void addSong(String lineToParse) {
String[] tokens = lineToParse.split("/");//使用split()方法来拆分文本
//songList.add(tokens[0]);//只加入第一项
Song nextSong = new Song(tokens[0], tokens[1], tokens[2], tokens[3]);
songList.add(nextSong);
}
}
class Song implements Comparable<Song> {
String title;
String artist;
String rating;
String bpm;
public int compareTo(Song s) {
return title.compareTo(s.getTitle());
}
Song(String t, String a, String r, String b) {//构造函数
title = t;
artist = a;
rating = r;
bpm = b;
}
public String getTitle() {//getter
return title;
}
public String getArtist() {//getter
return artist;
}
public String getRating() {//getter
return rating;
}
public String getBpm() {//getter
return bpm;
}
public String toString() {//将toString()覆盖,让他返回歌名
return title;
}
}