我是靠谱客的博主 单薄香菇,最近开发中收集的这篇文章主要介绍java collection接口_Java学习之容器上(Collection接口常用方法,Iterator接口,使用foreach循环遍历Collection集合元素,Set集合通用知识(Hashs...,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1.容器API的类图结构如下:

d64ef3ffbb1ab515a0e0a163efbfe22f.png

JAVA的集合类是一种特别有用的工具类,它可以用于存储数量不等的多个对象,并可以实现常用数据结构,如栈,队列等,除此之外,JAVA集合还可用于保存具有映射关系的关联数组。

JAVA的集合大致上可分为:Set,List和Map三种体系,其中Set代表无序,不可重复的集合;List代表有序,重复的集合,而Map则代表具有遇敌关系的集合。Queue体系集合,代表一种队列集合实现。

JAVA集合概述:

JAVA提供集合类主要负责保存盛装其他数据,因此集合类也被称为容器类。所有集合类都位于java.util包下。

JAVA集合类主要由两个接口派生而出:Collection和Map,也是根接口。

830e8cf2eb85f578a463225a8490d6af.png

78dacd141ebd0456b7b9ae181ff99daa.png

Map保存的每项数据都是key-value对,也就是由key和value两个值组成。

下面给个比喻,再给个图就非常容易理解了。

JAVA的所有集合分成三大类,其中Set 集合类似于一个罐子,把一个对象添加到Set集合时,Set集合无法记住添加这个元素的顺序,所以Set里的元素不能重复(否则系统无法准确识别这个元素)

List集合非常像一个数组,它可以记住每次添加元素的顺序,只是List长度可变。

Map集合也像一个罐子,只是它里面的每项数据都由两个值组成。

2f93c22856362434a32fdc3b64b0cf1c.png

如果访问List集合中的元素,可以直接根据元素的索引来访问,如果需要访问Map集合中的元素,可以根据每项元素的key来访问其value,如果希望访问Set集合中的元素,则只能根据元素本身来访问(这也是Set集合里元素不允许重复的原因)

对于Set,List和Map三种集合,最常用的实现类,分别是HashSet,ArrayList  ,,HashMap  三个实现类。

1.1 Collection接口:

Collection接口——定义了存取一组对象的方法,其子接口Set和List分别定义了存储方式。

(1)Set中的数据对象没有顺序且不可以重复。

(2)List中的数据对象有顺序且可以重复。

Collection接口所定义的方法:

方法

描述

Boolean add(Object o)

向集合中添加一个对象的引用

Void clear()

删除集合中的所有对象,即不再持有这些对象的引用

Boolean contains(Object o)

判断在集合中是否持有特定对象的引用

Boolean isEmpty()

判断集合是否为空

Iterator iterator()

返回一个Iterator对象,可用它来遍历集合中的元素

Boolean remove(Object o)

从集合中删除一个对象的引用

Boolean retainAll(Collection> c)

保留集合中的指定内容

Int size()

返回集合中元素的数目

Object[] toArray()

返回一个数组,该数组包含集合中的所有元素

Boolean equals(Object o)

对象比较

Int hashCode()

返回hash码

注意:相等的对象应该具有相等的 hash codes。容器类对象在调用remove,contains等方法时需要比较对象是否相等,这回涉及到对象类型的equals方法和hasCode方法;对于自定义的类型,需要重写equals和hashCode方法以实现自定义的对象相等规则。

Set接口和list接口都继承了Collection接口,而map接口没有继承Collection接口,因此可以对set对象和list对象调用以上方法,但是不能对Map对象调用以上方法。

Collection接口的iterator()和toArray()方法都用于获取集合中的所有元素,前者返回一个Iterator对象,后者放回一个包含集合中所有元素的数组。

增加Name类的equals和hashCode方法如下:

1 public booleanequals(Object obj){2 if(obj instanceofName){3 Name name=(Name)obj; return(firstName.equals(name.firstName)&&lastName.equals(name.lastName));

4 }5 return super.equals(obj);6 }7 public inthashCode(){8 returnfirstName.hashCode();9 }

方法应用例子:

1 importjava.util.ArrayList;2 importjava.util.Collection;3 importjava.util.HashSet;4 public classTestCollection{5 public static voidmain(String[] args){6 Collection c= newArrayList();7 c.add("孙悟空");8 c.add(6);9 System.out.println("c集合的元素的个数为:"+c.size());10 System.out.println("c集合里面是否包含孙悟空字符"+" "+c.contains("孙悟空"));11 c.add("世界你好");12 System.out.println("c集合里面的元素:"+c);13 Collection books=new HashSet(); //HashSet不允许元素重复。

14 books.add("世界你好");15 books.add("你好世界");16 System.out.println("c集合里面是否完全包含books:"+c.contains(books));17 c.removeAll(books);18 System.out.println("c集合中的元素:"+c);19 c.clear();20 System.out.println("c集合里面的元素:"+c);21 books.retainAll(c);22 System.out.println("books集合的元素:"+books);23

24 }25 }

输出结果:

c集合的元素的个数为:2

c集合里面是否包含孙悟空字符 true

c集合里面的元素:[孙悟空, 6, 世界你好]

c集合里面是否完全包含books:false

c集合中的元素:[孙悟空, 6]

c集合里面的元素:[]

books集合的元素:[]

1.2 Iterator接口:

使用Iterator接口遍历集合元素,Iterator接口是JAVA集合框架的成员,也被称为迭代器。

Iterator接口中声明了如下方法:

boolean hashNext():如果迭代的集合元素还没被遍历,则返回true

Object next():返回集合里下一个元素。

Void remove():删除集合里上一次next方法返回的元素。

1 importjava.util.Collection;2 importjava.util.HashSet;3 importjava.util.Iterator;4 public classTextIterator {5 public static voidmain(String[] args){6 Collection books=new HashSet(); //无序序列,元素不可重复

7 books.add("世界你好");8 books.add("你好世界");9 books.add("你好Java");10 System.out.println("现在结合的元素:"+books);11 Iterator it=books.iterator(); //获取books集合对应的迭代器。

12 while(it.hasNext()){13 String book=(String)it.next(); //it.next()方法返回的数据类型是object类型,需要强制类型转换。

14 System.out.println(book);15 if(book.equals("你好世界")){16 it.remove(); //从集合中删除上一次next方法返回的元素。

17 }18 book="测试字符串"; //对book变量赋值,不会改变集合元素本身。

19 }20 System.out.println(books);21

22

23 }

输出结果:

现在结合的元素:[世界你好, 你好Java, 你好世界]

世界你好

你好Java

你好世界

[世界你好, 你好Java]

Iterator仅用于遍历集合,Iterator本身并不提供盛装对象的能力,如果需要创建Iterator对象,则必须有一个被迭代的集合。

Iterator必须依附于Collection对象,有一个Iterator对象,则必然有一个怀之关联的Collection对象。Iterator提供了2个方法来迭代访问Collection集合里的元素。

结论:当使用Iterator对集合元素进行迭代时,Iterator并不是把集合元素本身传给了迭代变量,而是把集合元素的值传给了迭代变量,所以修改迭代变量的值对集合元素本身没有任何改变。

1.3使用foreach循环遍历集合元素

我们知道,除了可以使用Iterator类迭代访问Collection集合里的元素之外,现在还可以使用foreach循环来迭代访问集合元素会更加便捷。

foreach的语句格式:

for(元素类型t 元素变量x : 遍历对象obj){

引用了x的java语句;

}

1 importjava.util.Collection;2 importjava.util.HashSet;3

4 public classTextForeach {5 public static voidmain(String[] args){6 Collection books=newHashSet();7 books.add("世界您好");8 books.add("您好世界");9 books.add("您好JAVA");10 for(Object obj:books){11 String book=(String)obj; //此处的book变量也不是集合元素本身

12 System.out.println(book);13 if(book.equals("您好世界")) {14 books.remove(book);15 }16

17 }18

19 System.out.println(books);20

21 }

输出结果:

现在结合的元素:[世界你好, 你好Java, 你好世界]

世界你好

你好Java

你好世界

[世界你好, 你好Java]

1.4 Set集合的通用知识:

1.4.1HashSet类:

HashSet是Set接口的典型实现,大多数时候使用Set集合时就是使用这个实现类。HashSet按Hash算法一存储集合中的元素,因此具有很好的存取和查找性能。

特点:

》不能保证元素的排列顺序,顺序有可能发生变化。

》HashSet来是同步的,如果多个线程同时访问一个Set集合,如果多个线程同时访问一个HashSet,如果有2条或者2条以上线程同时修改了HashSet集合,必须通过代码来保证其同步。

》集合元素值可以是Null

我们可以简单的认为:HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值也相等。

1 import java.util.*;2 class A{ //类A的equals方法总是返回true,但没有重写其hashCode()方法

3 public booleanequals(Object obj){4 return true;5 }6 }7 class B{ //类B的hashCode()方法总是返回l,但没有重写equals()方法

8 public inthashCode(){9 return 1;10 }11 }12 class C{ //类C的hashCode()方法总是返回2,重写其equals()方法

13 public inthashCode(){14 return 2;15 }16 public booleanequals(Object obj){17 return true;18 }19 }20 public classTextHashset{21 public static voidmain(String[] args){22 HashSet books = newHashSet();23 books.add(newA());24 books.add(newA());25 books.add(newB());26 books.add(newB());27 books.add(newC());28 books.add(newC());29 30 }31 }

我们从编译结果可以看出,即使2个A对象通过equals比较返回true,但HashSet依然把它们当成2个,即使2个B对象的hashCode()返回相同值(都是1)但,HashSet依然把它们当成2个对象。

简单的提醒点:

如果需要某个类的对象保存到HashSet集合中,重写这个类的equals()方法和hashCode()方法时,应该尽量保证两个对象通过equals比较返回true时,它们的hashCode方法返回值也相等。

HashSet采用每个元素的hashCode作为其索引,从而可以自由增加HashSet的长度,并可以根据元素的hashCode值来访问该元素。

(我们可以理解为相当于数组里的下标索引)。

因为hashCode()方法很重要,看看重写hashCode()方法的基本规则。

》当两个对象通过equals方法比较返回true时,这个两个对象的hashCode应该相等。

》对象中用作equals比较标准的属性,都应该用来计算hashCode值。

5c1d23444ec75030863b9626042a36aa.png

1 importjava.util.Iterator;2

3 classR{4 intcount;5 public R(intcount){6 this.count=count;7 }8 publicString toString(){9 return "R[count"+count+"]";10 }11 public booleanequals(Object obj){12 if(obj instanceofR){13 R f=(R)obj;14 if(f.count==this.count){15 return true;16 }17 }18 return false;19 }20 public inthashCode(){21 return this.count;22 }23 }24 public classTestHashSet2{25 public static voidmain(String[] args){26 HashSet hs=newHashSet();27 hs.add(new R(5));28 hs.add(new R(-3));29 hs.add(new R(9));30 hs.add(new R(-2));31 System.out.println("第1个hs,集合中的元素:"+hs+"n"); //打印HashSet集合,集合元素没有重复

32 Iterator it=hs.iterator();33 R first =(R)it.next();34 first.count = -3; //为第一个元素的count实例变量赋值

35 System.out.println("第2个hs,集合中的元素:"+hs+"n");36 hs.remove(new R(-3)); //删除count为-3的R对象

37 System.out.println("第3个hs,集合中的元素:"+hs+"n");38 System.out.println("hs是否包含count为-3的R对象?"+hs.contains(new R(-3))); //输出false

39 System.out.println("hs是否包含count为5的R对象"+hs.contains(new R(5))); //输出false

40 }41 }

输出结果:

第1个hs,集合中的元素:[R[count5], R[count9], R[count-3], R[count-2]]

第2个hs,集合中的元素:[R[count-3], R[count9], R[count-3], R[count-2]]

第3个hs,集合中的元素:[R[count-3], R[count9], R[count-2]]

hs是否包含count为-3的R对象?false

hs是否包含count为5的R对象false

ps:

(1)object类中的hashcode()方法比较的是对象的地址(引用地址),使用new方法创建对象,两次生成的当然是不同的对象,造成的结果就是两个对象的hashcode()返回的值不一样。所以hashset会把new方法创建的两个它们当作不同的对象对待,

(2)在java的集合中,判断两个对象是否相等的规则是:

a),判断两个对象的hashCode是否相等

如果不相等,认为两个对象也不相等,完毕

如果相等,转入2)

(这一点只是为了提高存储效率而要求的,其实理论上没有也可以,但如果没有,实际使用时效率会大大降低,所以我们这里将其做为必需的。)

b),判断两个对象用equals运算是否相等

如果不相等,认为两个对象也不相等

如果相等,认为两个对象相等(equals()是判断两个对象是否相等的关键)

LinkedHashSet类:

HashSet还有一个子类LinkedHashSet,它也是根据元素hashCode值来决定元素存储位置,它是需要维护元素的插入顺序,因此性能略低于HashSet的性能,但在迭代访问Set里的全部元素时将有很好的性能,因为它以链表来维护内部顺序。

1 importjava.util.LinkedHashSet;2 public classLinkedHashSetTest{3 public static voidmain(String[] args){4 LinkedHashSet books = newLinkedHashSet();5 books.add("世界您好");6 books.add("您好世界");7 System.out.println(books);8 books.remove("世界您好"); //删除世界您好

9 books.add("世界您好"); //重新添加世界您好

10 System.out.println(books);11 }12 }

输出结果:

[世界您好, 您好世界]

[您好世界, 世界您好]

编译结果相信大家都理解,因为元素的顺序正好与添加顺序一致。

最后

以上就是单薄香菇为你收集整理的java collection接口_Java学习之容器上(Collection接口常用方法,Iterator接口,使用foreach循环遍历Collection集合元素,Set集合通用知识(Hashs...的全部内容,希望文章能够帮你解决java collection接口_Java学习之容器上(Collection接口常用方法,Iterator接口,使用foreach循环遍历Collection集合元素,Set集合通用知识(Hashs...所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(72)

评论列表共有 0 条评论

立即
投稿
返回
顶部