为什么要用HashSet呢,因为要防止重复!为什么使用TreeSet呢,因为HashSet不可以排序!
在list的基础上,添加如下代码:
HashSet<Song> songSet=new HashSet<Song>();
//如果使用TreeSet,则为:
//TreeSet<Song> songSet=new TreeSet<Song>();
songSet.addAll(songList);
System.out.println(songSet);
如果想把两个不同的Song对象视为相等的,就必须覆盖过从Object继承下来的hashCode()方法与equals()方法。
由于内存问题,必须覆盖hashCode()才能确保两个对象有相同的hashcode,也要确保以另一个对象为参数的equals()调用会返回true。
重写hashCode()与equals()的代码:
public boolean equals(Object asong){
Song s=(Song)asong;
return getTitle().equals(s.getTitle());
}
public int hashCode(){
return title.hashCode();
}
//示例代码:
if(foo.equals(bar)&&foo.hashCode()==bar.hashCode()){
//两个引用指向同一个对象,或者两个对象是相等的。
}
hashCode()与equals()的相关规定:
API文件有对对象的状态制定出必须遵守的规则:
(1)如果连个对象相等,则hashcode必须也是相等的。
(2)如果两个对象相等,对其中一个对象调用equals()必须返回true。也就是说,若a.equals(b)则b.equals(a)。
(3)如果两个对象有相同的hashcode值,它们也不一定是相等的。但若两个对象相等,则hashcode值一定是相等的。
(4)因为若equals()被覆盖过,则hashCode()也必须被覆盖。
(5)hashCode()的默认行为是对在heap上的对象产生独特的值。如果你没有override过hashCode(),则该class的两个对象怎样都不会被认为是相同的。
(6)equals()的默认行为是执行==的比较。也就是说会去测试两个引用是否对上heap上同一个对象。如果equals()没有被覆盖过,两个对象永远不会被视为相同的,因为不同的对象有不同的字节组合。
a.equals(b) 必须与a.hashCode()==b.hashCode()等值。
但a.hashCode()==b.hashCode()不一定要与a.equals等值。
为什么不同对象会有相同的hashcode的可能?
因为hashCode()所使用的杂凑算法也许刚好会让多个对象传回相同的杂凑值。
hashcode是用来缩小寻找成本,但最后还是要用equals()才能认定是否真的找到相同的项目。
关于泛型的笔记:TestGenerics1.java
import java.util.*;
public class TestGenerics1{
public static void main(String[] args){
new TestGenerics1().go();
}
public void go(){
/*Animal[] animals={new Dog(),new Cat(),new Dog()};
Dog[] dogs={new Dog(),new Dog(),new Dog()};
takenAnimals(animals);
takenAnimals(dogs); */
ArrayList<Animal> animals=new ArrayList<Animal>();
animals.add(new Dog());
animals.add(new Cat());
animals.add(new Dog());
takeAnimals(animals);
ArrayList<Dog> dogs=new ArrayList<Dog>();
dogs.add(new Dog());
dogs.add(new Dog());
takeAnimals(dogs); //方法二时,这行代码无法通过编译
//将产生的错误如下(使用takeAnimals方法二):
/*
TestGenerics1.java:22: 无法将 TestGenerics1 中的 takeAnimals(java.util.ArrayList
<Animal>) 应用于 (java.util.ArrayList<Dog>)
takeAnimals(dogs);
^
1 错误
*/
/*
上面代码没问题,但是如下代码有就会有问题了。
public void takeAnimals(ArrayList<Animal> animals){
animals.add(new Cat())
}
如果把方法声明成取用ArrayList<Animal>,它就只会取用ArrayLis<Animal>参数,ArrayList<Dog>与ArrayList<Cat>都不行。
数组的类型是在运行期间检查的,但集合的类型检查只会发生在编译期间
takeAnimals(Animal[] animals)函数中写入animals[0]=new Cat();调用takeAnimals(dogs)编译时不会出错~
*/
}
//takeAnimals方法一
/*public void takenAnimals(Animal[] animals){
for(Animal a:animals){
a.eat();
}
}*/
//takeAnimals方法二
/*public void takeAnimals(ArrayList<Animal> animals){
for(Animal a:animals){
a.eat();
//animals.add(new Cat()); //这行代码无法通过编译
}
}*/
//takeAnimals方法三
public <T extends Animal>void takeAnimals(ArrayList<T> animals){
for(Animal a:animals){
a.eat();
//animals.add(new Cat()); //这行代码无法通过编译
}
}
/*
方法中使用万用字符,编译器阻止任何可能破坏引用参数所指集合的行为。
animals.add(new Cat());仍然无法通过编译
*/
}
//-----------------------------------------------------------------------------
abstract class Animal
{
void eat(){
System.out.println("animal eating");
}
}
class Dog extends Animal
{
void bark(){}
}
class Cat extends Animal
{
void meow(){}
}
/*
方法中使用完用字符的两种形式:
1.public void takeThing(ArrayList<? extends Animal> list)
2.public <T extends Animal> void takeThing(ArrayList<Tl> list)
如果方法中含有多个参数,这种形式将比较简便
*/
后记:觉得head first java某些东西还是讲的复杂了。比如关于takeAnimals(ArrayList<Animal> animals)方法的部分,只说只能传入Animal类的对象、而不是Animal子类的对象,就可以了啊。
分享到:
相关推荐
《Head First Java.第二版.中文完整高清版.pdf》是一本广受Java学习者欢迎的教程书籍,它不仅提供了对Java语言的详细介绍,而且强调了学习方法,通过各种有趣的方式帮助读者更好地理解和记忆Java编程的核心概念。这...
《Head First Java》PDF版本下载
[Head.First.Design.Patterns].Head.First.Design.Patterns.7z [Head.First.Design.Patterns].Head.First.Design.Patterns.7z [Head.First.Design.Patterns].Head.First.Design.Patterns.7z [Head.First.Design....
Head First系列在各个细分领域和技术都是非常好的[入门]书籍. 这一系列书籍的共同点就在于,对于功能的介绍基本都是秉承[设定目标 - 设计最初解决方案 -> 遇到问题 -> 借助解决问题的需求,介绍新的技术或者功能 -> ...
《Head First Java》是Java初学者的一本经典教材,第二版更是深受读者喜爱。这本书以其独特的教学方式,通过丰富的图像、幽默的插图和互动性的设计,帮助学习者轻松掌握复杂的Java编程概念。以下是该书涉及的一些...
《Head First Java》是本完整的面向对象(object-oriented,OO)程序设计和Java的学习指导。此书是根据学习理论所设计的,让你可以从学习程序语言的基础开始一直到包括线程、网络与分布式程序等项目。最重要的,你会...
《Head First Java》是一本非常受欢迎的Java编程学习书籍,其中文高清版为中国的Java初学者提供了方便易懂的学习资源。这本书以其独特的教学方式,通过丰富的图表、幽默的插图和非传统的方式深入浅出地讲解Java编程...
《Head First Java》是一本受到广泛好评的Java学习书籍,下面将详细解读文件中提及的关于这本书以及Java学习的关键点。 首先,文件中提到了这本书在计算机图书界受到的荣誉和评价。《Head First Java》在2003年被...
《HeadFirstJava》(中文版)(第2版)是本完整的面向对象(object-oriented,OO)程序设计和Java的学习指导。此书是根据学习理论所设计的,让你可以从学习程序语言的基础开始一直到包括线程、网络与分布式程序等项目。最...
- **基本语法**:介绍Java的基本语法结构,如变量声明、数据类型、运算符等。 - **控制流语句**:讲解条件语句(if-else)、循环语句(for、while)等,这些是编写程序的基础。 - **数组与集合**:介绍数组的基本...
Head First Python, 2nd Edition.zip.001 Head First Python, 2nd Edition.zip.001 Head First Python, 2nd Edition.zip.001 Head First Python, 2nd Edition.zip.001 Head First Python, 2nd Edition.zip.001 Head ...
dddHead First Python, 2nd Edition.zip.002Head First Python, 2nd Edition.zip.002Head First Python, 2nd Edition.zip.002Head First Python, 2nd Edition.zip.002Head First Python, 2nd Edition.zip.002Head ...
《Head First Java》是一本非常受欢迎的Java编程学习书籍,其中文版的出现为中文读者提供了更方便的学习途径。这本书以其独特的教学方式,通过丰富的图像、故事和游戏,帮助初学者轻松理解复杂的Java编程概念。以下...
《Head First Java》是一本非常受欢迎的Java编程学习书籍,其中文高清版为中国的Java初学者提供了方便的学习资源。这本书以其独特的教学方式,通过丰富的图像、幽默的插图和互动性的设计,帮助读者以轻松有趣的方式...
《Head First Java》第三版是一本广受好评的编程教材,特别适合初学者和有经验的程序员用以学习或复习Java语言。这本书以其独特的教学方式,将枯燥的编程知识转化为生动有趣的内容,使读者在轻松愉快的氛围中掌握...