集合

常用的集合有ArrayList,TreeSet,HashMap,HashSet.

ArrayList

最常用的集合,每次插入都在后面追加元素。

TreeSet

以有序状态保持并可防止重复。当你需要set集合或元素按照一定的顺序排列时,它会很好用。当然,这需要付出一定的成本,每当插入新项目时,它必须要花时间找到适当的位置,而ArrayList只要把项目放在最后就行。

TreeSet的元素必须是Comparable的,你必须指出对象应该如何排序。我们已经在上面讲过,方法有两种,分别是:

实现Comparable类。

使用重载,取用Comparator参数的构造函数来创建TreeSet,就像sort()的使用一样。

class ArtistCompare implements Comparator{

public int compare(Song one,Song two){

return one.getAtist().compareTo(two.getArtist());

}

}

ArtistCompare artCompare=new ArtistCompare();

TreeSet tree=new TreeSet(artCompare);

HashMap

针对经常插入或删除中间元素所设计的高效率集合。

使用方法:

HashMap scores=new HashMap();

scores.put("Kathy",20);

scores.put("Jim",22);

System.out.println(scores.get("Jim"));

HashSet的遍历方法:

Iterator iter = scores.entrySet().iterator();

while (iter.hasNext()) {

Map.Entry entry = (Map.Entry) iter.next();

Object key = entry.getKey();

Object val = entry.getValue();

String relkey=(String)key;

Integer relval=(Integer) val;

doprocessing();

HashSet

防止重复的集合,可快速的寻找相符的元素。

这里有个问题,对象要怎样才算相等?是引用到完全相同的对象,还是可以使不同的对象,但是我们所关心的值相等。于是,引出一个关键问题:引用相等性和对象相等性。

引用相等性 堆上同一对象的不同引用,如果对这两个引用调用hashCode(),结果相同。如果没有被覆盖的话,hashCode()默认的行为会返回每个对象特定的序号,这个序号一般跟对象的内存位置有关,因此是唯一的。

如果想要知道两个引用是否相等,可以使用==来比较变量上的字节组合,如果引用到相同的对象,字节组合也会一样。

对象相等性 堆上的两个不同对象在意义上是相等的,如果你想把两个不同的对象视为相等,就必须override hashCode()和equals()函数。

hashCode()

HashSet使用hashcode来达到存取速度较快的存储方法,如果你尝试用对象来寻找ArrayList中的相同对象,(不用索引来找),ArrayList会从头开始找起,但HashSet不是,它是根据hashcode来找的,不需要从头找起。

重点在于hashcode相同并不一定保证对象时相等的,学过数据结构的同学肯定知道,hashCode()使用的杂凑算法很可能将多个对象传回相同的杂凑值,越糟糕的杂凑算法越容易碰撞,而且也跟数据值域的分布特性有关,因此如果两个对象的hashcode相同,并不能说它俩就相等,此时还需要使用equals()函数来进一步确认是否相等。你可以这样认为,hashcode用来缩小寻找成本,但是最后还需要equals()来确定是否真的找到了相同的对象。

hashCode()的默认行为时对在heap上的对象产生独特的值,如果你没有override过,则该class的两个对象永远不可能被认为是相同的。

class Song implements Comparable{

String title;

String artist;

public boolean equals(Object aSong ){

Song s = (Song) aSong;

return getTitle.equals(s.getTitle()); //String覆盖过equals(),我们可以调用。

}

public int hashCode(){

return title.hsahCode(); //String覆盖过hashCode(),我们直接调用就可以了。

}

public int compareTo(Song s){

return title.compareTo(s.getTitle());

}

public getTitle(){

return title;

}

public getAtirst(){

return artist;

}

}

euqals()

equals()的默认行为是执行==的比较,也就是说会去测试两个引用是否堆上heap上同一个对象,如果eqauls没有被覆盖过,两个对象永远都不会被视为相同的,因为不同的对象有不同的字节组合。

toString()

toString()是定义在Object类里的,所以每个java类都会继承到,且因为对象被System.out.println(anObject)列出来时会调用toString(),所以当你想用被System.out.println输出你自定义的对象时,你需要重定义toString().

泛型

只要你再java程序或文件中看到<>这一组符号,就代表泛型正在起作用。泛型的主要目的是让你写出有类型安全性的集合,也就是,让编译器能够帮忙防止你把Dog放到一群Cat中。

使用泛型的两种方法:

使用定义在类声明的类型参数:

public class ArrayList extends AbstractList...{

public boolean add (E o)

...

}

使用未定义在类声明的参数 public void takeThing (ArrayListlist)

Collections.sort()

Collections.sort()是集合的常用方法,它只接受Comparable对象的list。因此,如果你自定义了一个类,然后生成了很多类对象,并存入集合中,如果你期望用Collections.sort()来对它们进行排序。你需要对你的自定义类做额外的工作。

你有两种方法:

第一种,实现Comparable 类,并覆盖它的int compareTo(T o)方法 java.lang.Comparable接口:

public interface Comparable{

int compareTo(T o);

}

class Song implements Comparable{

String title;

String artist;

public int compareTo(Song s){

return title.compareTo(s.getTitle());

}

public getTitle(){

return title;

}

public getAtirst(){

return artist;

}

}

第二种,自制Comparator

使用compareTo()方法时,list中的元素只能有一种将自己与同类型的另一元素相比较的方法。但Comparator是独立于所比较元素类型之外的--它是独立的类。因此,你可以有各种不同的比较方法。例如,除了按照title排序,你也可以按照artist排序。

因此,取用Comparator版的sort()方法会用Comparator而不是内置的 compareTo()方法。有如下规则:

调用单一参数的sort(List o)方法代表由list元素上的compareTo()方法来决定顺序。因此元素必须实现Comparable这个接口。 调用sort(List o,Comparator c)方法代表不会调用list元素的compareTo()方法,而会使用Comparator的compare()方法,这也意味着list元素不用实现

Comparable.

class ArtistCompare implements Comparator{

public int compare(Song one,Song two){

return one.getAtist().compareTo(two.getArtist());

}

}

ArtistCompare artCompare=new ArtistCompare();

Collections.sort(songList,artCompare);

集合的多态

数组的多态

如果方法的参数是Animal的数组,它也能够取用Animal次类型的数组。

Animal [] animals={new Dog(),new Cat(),new Dog()};

Dog [] dogs={new Dog(),new Dog(),new Dog()};

takeAnimals(animals);

//takeAnimals()能够存取Animal[]或Dog[]参数,因为Dog也是一个Animal,多态在此处起作用

takeAnimals(dogs);

public void takeAnimals(Animal [] animals){

for(Animal a : animals){

a.eat();}

}

abstract class Animal{

void eat(){}

}

class Dog extends Animal{

void bark(){}

}

class Cat extends Animal{

void meow(){}

}

ArrayList的多态

ArrayList animals= new ArrayList();

animals.add(new Dog());

animals.add(new Dog());

animals.add(new Dog());

takeAnimals(animals);

public void takeAnimals(ArrayList animals){

for(Animal a : animals){

a.eat();}

}

因为多态的关系,编译器会让Dog数组通过取用Animal数组参数的方法,这没有问题,问题是ArrayList< Animal >参数能接受ArrayList< Dog >吗,回答是,不行。如果我们在上面的程序里加上这一段,将出现编译错误。

ArrayListdogs = new ArrayList();

dogs.add(new Dog());

dogs.add(new Dog());

takeAnimals(dogs);

可能很多同学会疑惑,毕竟多态的意义就在于Animal能做的事情,Dog也能做,但你想过吗,如果我们的takeAnimals()是这样的:

public void takeAnimals(ArrayList animals){

animals.add(new Cat());

}

这就会有问题了,理论上把Cat加到ArrayList< Animal >是合法的,这也是使用Animal的本意--让各种Animal都可以加入到此ArrayList中。但是如果你传入的是一个Dog的ArrayList给该方法,那么将会是Cat强行加入了一个Dog ArrayList中,编译器当然不会让这种事情发生。

所以,如果把方法声明成ArrayList< Animal >,它只能接受ArrayList< Animal >的参数,ArrayList< Dog>和ArrayList< Cat>都不行。

很多同学肯定又要问了,那为什么数组可以过关,而ArrayList却不行,毕竟数组也会遇到这样的问题啊。

其实这跟jvm有关,数组类型是在运行期间检查的,但集合的类型检查发生在编译期间。

下面这段程序在编译时不会出错,但运行时出错。

Dog [] dogs={new Dog(),new Dog(),new Dog()};

takeAnimals(dogs);

public void takeAnimals(Animal [] animals){

animals[0]=new Cat();

}

那有没有一种方法,让我们能够使用多态化的集合参数,就像数组那样,这样我们就可以传入Cat,Dog的集合了,只要我们自己保证不会做出格的行为,比如往Cat集合中加入Dog等等。

万能的java当然有办法,使用这种声明方式:

public void takeThing(ArrayListlist)

当你这样声明函数时,编译器会阻止任何可能破坏引用参数所指集合的行为。也就是,你可以调用list中任何元素的方法,但是不能加入元素。

也就是说你可以操作集合元素,但是不能增加集合元素。如此才能保障执行期间的安全性。编译器会阻止执行期的恐怖活动。

所以下面的程序是可行的:

for (Animal a :animals){a.eat();}

但这个就过不了编译:

animals.add(new Cat());

java 泛型和集合_Java集合和泛型相关推荐

  1. 中转换成list集合_Java集合、数组与泛型中的几个陷阱,你掉进了几个?

    来源:苦逼的码农(ID:di201805) 下面我总结了集合.泛型.数组转集合等一些常见的陷进,认真看完,相信你绝对有所收获. 1.List ,List> 与 List 有区别吗? 说实话,我敢 ...

  2. java list取值_Java集合详解

    一.集合的由来 通常,我们的程序需要根据程序运行时才知道创建多少个对象.但若非程序运行,程序开发阶段,我们根本不知道到底需要多少个数量的对象,甚至不知道它的准确类型.为了满足这些常规的编程需要,我们要 ...

  3. java中的集合_Java 集合介绍,常用集合类

    JAVA 集合 在处理数据的过程中经常会需要一个容器来存储某一类型的数据,Java 中的数组就是这样一种容器.但 Java 中的数组有其局限性,定义后的数组长度不可变,超出数组长度后就不能再存放数据了 ...

  4. java集合替换集合_Java集合–您必须知道的13件事

    java集合替换集合 Java Collections Framework is one of the core parts of the Java programming language. Col ...

  5. java hashset 源码_Java集合源码分析-HashSet和LinkedHashSet

    前两篇文章分别分析了Java的ArrayList和LinkedList实现原理,这篇文章分析下HashSet和LinkedHashSet的源码.重点讲解HashSet,因为LinkedHashSet是 ...

  6. 集合_java集合框架

    java集合框架图 简化图: Java平台提供了一个全新的集合框架."集合框架"主要由一组用来操作对象的接口组成. 不同接口描述一组不同数据类型.      1.Java 2集合框 ...

  7. java的map集合_Java集合之Map

    正文 Map的特点? 通过Map接口的泛型我们可以看出:Map一次添加一对元素,存储的是键值对:而Collection接口一次添加一个元素. Map接口中的key是唯一的. Map的常见方法? 1.添 ...

  8. java list详解_java集合List解析

    作为一个Developer,Java集合类是我们在工作中运用最多的.最频繁的类.相比于数组(Array)来说,集合类的长度可变,更加适合于现代开发需求: Java集合就像一个容器,可以存储任何类型的数 ...

  9. java 创建集合类数组_Java集合 -- ArrayList集合及应用

    JAVA集合 对象数组 集合类之ArrayList 学生管理系统 斗地主案例 NO.one 对象数组 1.1 对象数组描述 A:基本类型的数组:存储的元素为基本类型 int[] arr={1,2,3, ...

最新文章

  1. python django vue_Django+Vue.js构建项目
  2. MyBatis接口的简单实现原理
  3. mac python3.8怎样安装scrapy_Python爬虫与mac下Scrapy配置
  4. 阿里开源那个牛哄哄问题排查工具竟然不会用?最佳实践来了!
  5. 网易云音乐一键听歌300首_网易云打卡,一键听歌300首。
  6. jmeter生成html报告修改,jmeter:测试后生成html报告
  7. 高并发图片实时渲染技术在阿里妈妈的大规模应用
  8. ltrim函数_MySQL|trim() 函数用法
  9. 中止请求和超时 跨域的HTTP请求 认证方式 JSONP
  10. 基础01类与对象、封装、构造方法
  11. python 实现冒泡排序
  12. 网易视频云技术分析:IOS工程常见问题解决方法
  13. windows7修复计算机在哪里找,Windows7系统修复方法大全
  14. 随便说说,中国开发人员的不同层次和一些思考。
  15. 东汉唯物主义哲学家——王充
  16. 2020计算机博弈大赛幻影围棋分组第二天 围棋规则学习
  17. Git(七)——删除历史版本,保留当前状态
  18. gc System.gc() fullGC
  19. HDI PCB,这篇文章告诉与HDI相关的知识与工艺
  20. 漫步者lollipods如何调节音量_漫步者LolliPods怎么配对双耳-使用教程

热门文章

  1. CL_FXS_URL_DATA_FETCHER - a good utility to fetch picture binary data according to url
  2. App in Scala
  3. 使用Fiddler为满足某些特定格式的网络请求返回mock响应
  4. CRM User status optimization - heavy calculation logic of status filter
  5. where is page layout xml template being initialized - hard code in ctr
  6. 介绍一种在ABAP内核态进行内表高效拷贝的方法,和对应的Java和JavaScript版本的伪实现
  7. SAP UI5 that.getView().bindElement(that.Context)
  8. SAP Marketing Cloud功能简述(五) : 销售计划管理
  9. SAP Leonardo平台机器学习API的一些错误处理机制
  10. CRM 702和CRM 712的区别