java set collection_JAVA集合一之集合简介(Collection,List,Set)

在编写JAVA程序中,我们经常会遇到需要保存一组数据对象,此时,我们可以采用对象数组来进行多个对象的保存,但对象数组存在一个最大的问题即在于长度上的限制,如果说我们现在要保存一组对象,但是我们并知道数组对象到底有多少个的时候,那么此时就遇到了困难,因此为了解决此问题,在JDK1.2中,提出了类集框架的概念,并在JDK1.5中对此框架进行了修改,加入了泛型的支持,从而保证了操作的安全性。而在整个集合中,提供了几个集合核心操作的接口,分别为:Collection、Set、List、Enumeration、Iterator、ListIterator等。

1)单值保存的最大父接口:Collection

所谓的单值保存指的是每次操作只保存一个对象,每次增加只增加一个对象,而在Collection接口之中定义了如下几个常用的方法:

packagecom.njupt.study.collection;importjava.util.Iterator;public interface Collection extends Iterable{/*** 增加数据

*@parame

*@return

*/

booleanadd(E e);/*** 删除指定的元素

*@paramo

*@return

*/

booleanremove(Object o);/*** 清除数据*/

voidclear();/*** 判断集合是否为空

*@return

*/

booleanisEmpty();/*** 获取元素的个数

*@return

*/

intsize();/*** 查找一个数据是否存在

*@paramo

*@return

*/

booleancontains(Object o);/*** 将集合变为对象数组后返回

*@return

*/Object[] toArray();/*** 将集合变为指定类型的对象数组

*@param

*@parama

*@return

*/

T[] toArray(T[] a);/*** 为Iterator接口实例化,来源于父类接口Iterable*/Iteratoriterator();

}

Collection接口本身在开发之中并不会直接的去使用,而在开发之中往往会使用两个子接口:List、Set。

2)允许重复的子接口:List

List接口是Collection接口的子接口,是有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。

public interface Listextends Collection

List接口对Collection接口进行了大量的扩充操作,而主要的扩充方法有如下几个:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public interface List extends Collection{/*** 返回指定位置上的数据

*@paramindex

*@return

*/E get(intindex);/*** 修改指定位置上的数据

*@paramindex

*@paramelement

*@return

*/E set(intindex, E element);/*** 为ListIterator接口实例化

*@return

*/ListIteratorlistIterator();

}

View Code

List本身也是一个接口,所以如果要想使用这个接口就必须有子类,实现List接口的集合主要有:ArrayList、LinkedList、Vector、Stack。

ArrayList:

在List接口里面ArrayList子类的使用几率是最高的,一般List接口实例化,一般想到的为ArrayList。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagecom.njupt.study.collection;2

3 importjava.util.ArrayList;4 importjava.util.List;5

6 classStudent7 {8 privateString name;9

10 private intage;11

12 publicStudent(){};13

14 public Student(String n,inta)15 {16 this.name =n;17 this.age =a;18 }19

20 publicString getName() {21 returnname;22 }23

24 public voidsetName(String name) {25 this.name =name;26 }27

28 public intgetAge() {29 returnage;30 }31

32 public void setAge(intage) {33 this.age =age;34 }35

36 }37

38

39 public classDemo02 {40

41 public static voidmain(String[] args) {42 List list = new ArrayList();43

44 list.add(new Student("zhangsan",18));45

46 list.add(new Student("lisi",19));47

48 list.add(new Student("wangwu",17));49

50 System.out.println(list);51

52 System.out.println("******************");53

54 for(int i=0;i

View Code

输出结果为:

[com.njupt.study.collection.Student@1fc4bec, com.njupt.study.collection.Student@dc8569, com.njupt.study.collection.Student@1bab50a]

******************

com.njupt.study.collection.Student@1fc4bec

com.njupt.study.collection.Student@dc8569

com.njupt.study.collection.Student@1bab50a

为了显示更加明显的信息,因此增加重写toString()方法,

public String toString()

{

return this.name+"---->"+this.age;

}

显示结果为:

[zhangsan---->18, lisi---->19, wangwu---->17]

******************

zhangsan---->18

lisi---->19

wangwu---->17

可以看见ArrayList采用的为数组方式保存元素对象。

add 为添加元素,那么remove 可以删除元素,那么我们试试删除元素:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagecom.njupt.study.collection;2

3 importjava.util.ArrayList;4 importjava.util.List;5

6 classStudent7 {8 privateString name;9

10 private intage;11

12 publicStudent(){};13

14 public Student(String n,inta)15 {16 this.name =n;17 this.age =a;18 }19

20 publicString getName() {21 returnname;22 }23

24 public voidsetName(String name) {25 this.name =name;26 }27

28 public intgetAge() {29 returnage;30 }31

32 public void setAge(intage) {33 this.age =age;34 }35

36 publicString toString()37 {38 return this.name+"---->"+this.age;39 }40 }41

42

43 public classDemo02 {44

45 public static voidmain(String[] args) {46 List list = new ArrayList();47

48 list.add(new Student("zhangsan",18));49

50 list.add(new Student("lisi",19));51

52 list.add(new Student("wangwu",17));53

54 System.out.println(list);55

56 System.out.println("******************");57

58 for(int i=0;i

63 System.out.println("*********删除元素*************");64

65 list.remove(new Student("wangwu",17));66 for(int i=0;i

71 }72 }

View Code

输出结果为:

[zhangsan---->18, lisi---->19, wangwu---->17]

******************

zhangsan---->18

lisi---->19

wangwu---->17

*********删除元素*************

zhangsan---->18

lisi---->19

wangwu---->17

可以看见元素并没有被删除,为什么呢?  那我们试试非自定义对象是否可以删除呢?

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagecom.njupt.study.collection;2

3 importjava.util.ArrayList;4

5 public classDemo01 {6

7 /**

8 *@paramargs9 */

10 public static voidmain(String[] args) {11 java.util.List list = new ArrayList();12

13 list.add("a");14

15 list.add("b");16

17 list.add("c");18

19 System.out.println(list);20

21 for (int x = 0; x < list.size(); x++) {22 System.out.println(list.get(x));23 }24

25 list.remove("c");26

27 System.out.println("**********************");28

29 for (int x = 0; x < list.size(); x++) {30 System.out.println(list.get(x));31 }32 }33

34 }

View Code

显示结果为:

[a, b, c]

a

b

c

**********************

a

b

我们发现是可以删除的,为什么我们自己定义的不能删除呢?我们看下String的源码有什么不同?

public boolean equals(Object anObject) {

if (this == anObject) {

return true;

}

if (anObject instanceof String) {

String anotherString = (String)anObject;

int n = count;

if (n == anotherString.count) {

char v1[] = value;

char v2[] = anotherString.value;

int i = offset;

int j = anotherString.offset;

while (n-- != 0) {

if (v1[i++] != v2[j++])

return false;

}

return true;

}

}

return false;

}

原因应该就是上面的,因为对象在删除的时候,需要判断集合中的对象和要删除的对象是否一致,然后才能删除,但我们自定义对象中,并没有重写equals方法所以,删除的时候没有成功,为此,我们增加equals方法试试如何?

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 public booleanequals(Object obj)2 {3 if(this ==obj)4 {5 return true;6 }7

8 if(obj == null)9 {10 return false;11 }12

13 if( ! (obj instanceofStudent) )14 {15 return false;16 }17

18 Student other =(Student) obj;19

20 if(this.name.equals(other.name) && this.age ==other.age)21 {22 return true;23 }24 return false;25 }

View Code

显示结果为:

[zhangsan---->18, lisi---->19, wangwu---->17]

******************

zhangsan---->18

lisi---->19

wangwu---->17

*********删除元素*************

zhangsan---->18

lisi---->19

已成功删除。

注意:

既然ArrayList类可以为List接口实例化,那么也就可以为Collection接口实例化,但是这个时候已经不可以继续使用get()方法操作了,所以此时只能够将Collection变为对象数组后返回。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.njupt.study.collection;importjava.util.ArrayList;importjava.util.Collection;importjava.util.List;classStudent

{privateString name;private intage;publicStudent(){};public Student(String n,inta)

{this.name =n;this.age =a;

}publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}public intgetAge() {returnage;

}public void setAge(intage) {this.age =age;

}public booleanequals(Object obj)

{if(this ==obj)

{return true;

}if(obj == null)

{return false;

}if( ! (obj instanceofStudent) )

{return false;

}

Student other=(Student) obj;if(this.name.equals(other.name) && this.age ==other.age)

{return true;

}return false;

}/*public boolean equals(Object obj) {

if (this == obj) {

return true ;

}

if (obj == null) {

return false ;

}

if (! (obj instanceof Student)) {

return false ;

}

Student t = (Student) obj ;

if(this.name.equals(t.name ) && this.age == t.age) {

return true ;

}

return false ;

}*/

publicString toString()

{return this.name+"---->"+this.age;

}

}public classDemo02 {public static voidmain(String[] args) {

Collection list = new ArrayList();

list.add(new Student("zhangsan",18));

list.add(new Student("lisi",19));

list.add(new Student("wangwu",17));

System.out.println(list);

System.out.println("******************");

Student[] all= list.toArray(newStudent[]{});for(int i=0;i

{

System.out.println(all[i]);

}

}

}

View Code

2. LinkedList

同样实现List接口的LinkedList与ArrayList不同,ArrayList是一个动态数组,而LinkedList是一个双向链表。所以它除了有ArrayList的基本操作方法外还额外提供了insert方法在LinkedList的首部或尾部。

由于实现的方式不同,LinkedList不能随机访问,它所有的操作都是要按照双重链表的需要执行。在列表中索引的操作将从开头或结尾遍历列表(从靠近指定索引的一端)。这样做的好处就是可以通过较低的代价在List中进行插入和删除操作。

与ArrayList一样,LinkedList也是非同步的。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List:

List list = Collections.synchronizedList(new LinkedList(…));

ArrayList擅长于随机访问。同时ArrayList是非同步的。

3. Vector

Vector类是在JDK 1.0的时候所推出的最早的实现数据结构支持的类,其最早翻译为向量,但是到了JDK 1.2之后,为了使其可以继续使用,所以让这个类多实现了一个List接口,这样一来,就造成了Vector子类的操作方法比ArrayList更多,但是一般这些多的方法很少考虑。

与ArrayList相似,但是Vector是同步的。所以说Vector是线程安全的动态数组。它的操作与ArrayList几乎一样。

4.Stack

Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop 方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。

ArrayList和Vector的区别:

ArrayList和Vector都属于List接口的常用子类,这两者在操作形式以及概念上的区别如下:

No.

区别点

ArrayList

Vector

1

推出时间

JDK 1.2时推出,属于新的类

JDK 1.0时推出,属于旧的类

2

性能

使用异步处理方式,性能较高

采用同步处理操作,性能相对较低

3

安全性

非线程安全

线程安全

4

输出

因为Java主要从事于网络的开发,所以使用异步的处理操作形式要比使用同步(Synchronized)更多。

3)不允许重复的子接口:Set

Set接口与List接口最大的不同在于里面的数据不允许有重复,那么首先观察一下Set接口的继承结构:

public interface Set

extends Collection

Set是一种不包括重复元素的Collection,与List一样,它同样运行null的存在但是仅有一个。由于Set接口的特殊性,所有传入Set集合中的元素都必须不同,同时要注意任何可变对象,如果在对集合中元素进行操作时,导致e1.equals(e2)==true,则必定会产生某些问题。实现了Set接口的集合有:EnumSet、HashSet、TreeSet。

1.EnumSet

是枚举的专用Set。所有的元素都是枚举类型。

2.HashSet

哈希(Hash)是一种数据的排列算法,这种算法的典型操作就是加塞算法,那块有地就保存,所以只要带有hash都是无序的。HashSet堪称查询速度最快的集合,因为其内部是以HashCode来实现的。它内部元素的顺序是由哈希码来决定的,所以它不保证set 的迭代顺序;特别是它不保证该顺序恒久不变。

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagecom.njupt.study.collection;2

3 importjava.util.HashSet;4 importjava.util.Set;5

6 public classDemo03 {7

8 /**

9 *@paramargs10 */

11 public static voidmain(String[] args) {12 Set all = new HashSet();13 all.add("Hello");14 all.add("World");15 all.add("Hello"); //重复数据

16 System.out.println(all);17 }18

19 }

View Code

输出结果为:

[World, Hello]

通过本程序可以发现,里面所保存的顺序改变,而且如果有重复的数据也不能够保存。

3.TreeSet

在TreeSet子类里面所有保存的数据是没有重复的,而且可以为用户自动的进行排序。基于TreeMap,生成一个总是处于排序状态的set,内部以TreeMap来实现。它是使用元素的自然顺序对元素进行排序,或者根据创建Set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。

关于排序的说明:既然在TreeSet中的所有数据都可以排序,而且里面设置的数据也都是对象,那么下面就使用自定义类完成。

但是这个时候必须注意到一点:对于现在的TreeSet子类而言,由于其要对一组对象进行排序,那么这个对象所在的类就一定要实现Comparable接口,用于指定排序规则;

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 packagecom.njupt.study.collection;2

3 importjava.util.Set;4 importjava.util.TreeSet;5

6

7 class Student implements Comparable

8 {9 privateString name;10

11 private intage;12

13 publicStudent(){};14

15 public Student(String n,inta)16 {17 this.name =n;18 this.age =a;19 }20

21 publicString getName() {22 returnname;23 }24

25 public voidsetName(String name) {26 this.name =name;27 }28

29 public intgetAge() {30 returnage;31 }32

33 public void setAge(intage) {34 this.age =age;35 }36

37

38 public booleanequals(Object obj)39 {40 if(this ==obj)41 {42 return true;43 }44

45 if(obj == null)46 {47 return false;48 }49

50 if( ! (obj instanceofStudent) )51 {52 return false;53 }54

55 Student other =(Student) obj;56

57 if(this.name.equals(other.name) && this.age ==other.age)58 {59 return true;60 }61 return false;62 }63

64

65 publicString toString()66 {67 return this.name+"---->"+this.age;68 }69

70 @Override71 public intcompareTo(Student o) {72 if (this.age >o.age) {73 return 1;74 } else if (this.age

82 public classDemo04 {83

84 /**

85 *@paramargs86 */

87 public static voidmain(String[] args) {88 Set all = new TreeSet();89 all.add(new Student("张三",20)) ;90 all.add(new Student("李四",19)) ;91 all.add(new Student("王五",22)) ; //年龄一样

92 all.add(new Student("赵六",22)) ; //年龄一样

93 all.add(new Student("孙七",25)) ;94 all.add(new Student("孙七",25)) ; //插入了重复的数据

95 all.remove(new Student("李四",19)) ; //删除一个数据

96 System.out.println(all);97 }98

99 }

View Code

显示结果为:[张三---->20, 王五---->22, 赵六---->22, 孙七---->25]

需要注意:

实现了对自定义类对象的排序,并且可以判断重复元素,但是TreeSet类只是利用了Comparable完成了重复元素的判断,可是这种判断并不是真正意义上的重复元素判断。

如果说现在要想判断一个对象是否重复,严格来讲,这个操作是由Object类所提供的,在任何一个子类里面需要覆写Object类中的以下两个方法;

· 对象比较:public boolean equals(Object obj);

· 对象编码:public int hashCode();

hashCode()方法是用于进行对象编码计算的操作方法,如果要想进行对象的编码,那么肯定需要一些数学上的支持,这里就不详细讲解了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值