java集合的初步理解:集合

 

 

 

 

 

 

关于java集合的初步理解


一. 集合初始:


  1. 为什么要用集合:


面向对象的语言对事物的具体体现都是以事物的形式。

为了方便对多个对象的操作,就要对对象进行存储,另一方面,使用数组存储对象具有一些弊端,而集合就像是一种容器,可以动态的把多个对象的引用放入容器。

说到这里,不得不说一下数组的局限性:

1.数组只能通过下标操作存储的元素

2.数组的内存空间是连续分布的,而集合的内存空间不一定连续分布

3.数组的长度是固定的,长度的改变会产生新的数组,集合的长度是动态可变的,改变长度不会产生新的集合。

4.数组能存储引用数据和基本数据,集合只能存引用数据,集合更适合引用数据的具体操作

5.数组只能存一种类型的数据,而集合可以添加多种类型的数据

2. 集合的用途


用于存储数量不等的多个对象,还可以保存具有映射关系的关联数组

3. 集合的类别:


单列集合Collection接口和双列集合Map接口

1. Collection接口:分为Set接口和List接口

2. Map接口:具有映射关系的 key------value 对的集合

二. Collection接口:


1. Collection接口继承树


 

 

java集合的初步理解:集合

 

 

2. Collection接口的方法:


 

java集合的初步理解:集合

 

java集合的初步理解:集合

 

1.Collection 接口是List、Set 和Queue 接口的父接口,该接口里定义的方法既可用于操作Set 集合,也可用于操作List 和Queue 集合。

2.JDK不提供此接口的任何直接实现,而是提供更具体的子接口实现。

3. Collection集合的遍历

//遍历Collection集合创建迭代器对象 集合.iterator();

Collectionc2 = newArrayList();

c2.add("1");

c2.add("12");

c2.add("123");

c2.add("1234");

Iteratori = c2.iterator();

//在调用i.next()方法之前必须要调用 i.hasNext()方法进行判断

while(i.hasNext()) {//判断是否还有下一个元素 有向下进行

System.out.print(i.next()+" ");//取出当前的元素 指针下移

}

//迭代的过程不能对集合进行增删操作

System.out.println();

System.out.println(c2);

 

//遍历 增强for循环 内部 不能对迭代器进行增删操作

for(Object o:c2) {

System.out.print(o+" ");

}

4. Iterator:

1.Iterator对象称为迭代器(设计模式的一种),主要用于遍历Collection 集合中的元素。

2.所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象。

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

注意:迭代器只能用于遍历,不能用于集合元素的增删,否者会发生ConcurrentModificationException异常,在用foreach和Iterator时都有可能发生。

5. Collection接口的子接口


1. List接口:


1. 特点:

有序且可以重复

取代数组存储数据的局限性

可以根据序号索引存取容器的元素

常用类ArrayList LinkedList Vector

2. 方法:

void add(intindex, Object ele)

booleanaddAll(int index, Collection eles)

Objectget(int index)

intindexOf(Object obj)

intlastIndexOf(Object obj)

Objectremove(int index)

Object set(int index, Object ele)

List subList(int fromIndex, int toIndex)

3. 类:

ArrayList:底层是数组结构,本质上是对象引用的一个可变长的数组

LinkedList:底层是链表结构

注意:ArrayList查询快 LinkedList增删快,对于频繁使用增删操作的建议使用LinkedList

4. 代码:

public class TestList {

public static void main(String[] args) {

//< >之间放的是泛型 一般是引用数据类型

ArrayList list =new ArrayList();

//将数组转换为集合

int[] arr = {1,2,3,4};

//数组的工具类Arrays

List<int[]> arrlist = Arrays.asList(arr);

for (inti = 0; i < arrlist.size(); i++) {

for (intj = 0; j < arrlist.get(i).length; j++) {

//数组转化为集合相当于将数组当做一个元素放入集合中

intp = arrlist.get(i)[j];

System.out.println(p);

}

}

LinkedListlinklist =new LinkedList<>();

linklist.add(1);

linklist.add(12);

linklist.add(16);

System.out.println(list);

linklist.addFirst(15);

System.out.println(list);

linklist.addLast(30);

System.out.println(list);

intx = linklist.removeLast();//移出最后一个数据

System.out.println(x);

}

}

 

2. Set接口:


1. 特点:

没有提供额外的方法

自动去重,元素无序

根据equals()方法判断元素是否相同

2. 类:

HashSet:

HashSet是Set接口的典型实现,大多数的时候使用Set集合时都会使用这个集合

HashSet的底层实现是根据Hashcode来存储集合中的元素的,具有很好的存取和查找功能

特点:无序,不是线程安全的,集合元素可以为null

注意:当向HashSet 集合中存入一个元素时,HashSet 会调用该对象的hashCode() 方法来得到该对象的hashCode 值,然后根据hashCode 值决定该对象在HashSet 中的存储位置。

HashSet 集合判断两个元素相等的标准:两个对象通过hashCode() 方法比较相等,并且两个对象的equals() 方法返回值也相等

如果两个元素的equals() 方法返回true,但它们的hashCode() 返回值不相等,hashSet 将会把它们存储在不同的位置,但依然可以添加成功。

 

对于存放在Set容器中的对象,对应的类一定要重写equals()和hashCode(Object obj)方法,以实现对象相等规则。

重写hashCode()方法的基本原则:

在程序运行时,同一个对象多次调用hashCode() 方法应该返回相同的值

当两个对象的equals()方法比较返回true 时,这两个对象的hashCode() 方法的返回值也应相等

对象中用作equals()方法比较的Field,都应该用来计算hashCode 值

 

3. 代码:

public class TestSetColleation {

public static void main(String[] args) {

//HashSet集合的特点 无序且不重复

HashSet<Integer> set = new HashSet<Integer>();

set.add(1);

set.add(2);

//不允许重复

//如果set集合发现重复 就会覆盖重复值

set.add(1);//有重复 覆盖重复值

set.add(3);

System.out.println(set);

 

//HasdCode Hash值是有一定的范围的

//自动装箱

Integer i = Integer.valueOf(1);

inthash1 = i.hashCode();//算出Hash值

Integer j = Integer.valueOf(101);

inthash2 = j.hashCode();

if(hash1 == hash2) {

//调用 equals()方法 多个对象调用同一个哈希值 比较对象的内容是否一致

System.out.println("jjj");

//如果equals方法返回true则进行覆盖

}else {

System.out.println(1332);

}

 

//无序的

HashSet<String> set2 = newHashSet<String>();

set2.add("我");

set2.add("是");

set2.add("谁");

System.out.println("我".hashCode());

System.out.println("是".hashCode());

System.out.println("谁".hashCode());

System.out.println(set2);

 

test();

}

 

/**

* 从1 23 4 5 6 7 8 9 找出所有符合

*123 + 456 = 789

* 用 set集合

*/

private static void test() {

// TODO自动生成的方法存根

intsum = 0;

intcount = 0;

for (inti = 100; i < 1000; i++) {

for (intj = 999; j >=i; j--) {

int[] arr = newint[9];

HashSet<Integer> set = new HashSet<Integer>();

sum = i + j;

if(sum<1000) {

//找到每个位的数字

arr[0] = i%10;

arr[1] = i/10%10;

arr[2] = i/100;

 

arr[3] = j%10;

arr[4] = j/10%10;

arr[5] = j/100;

 

arr[6] = sum%10;

arr[7] = sum/10%10;

arr[8] = sum/100;

 

//判断0

for (intk = 0; k < arr.length; k++) {

if(arr[k] != 0) {

set.add(arr[k]);

if(set.size()==arr.length) {

count++;

System.out.println(i+"+"+j+"="+sum);

}

}

}

}

}

}

System.out.println(count);

}

}

LinkedHashSet:HashSet的子类,有序不允许重复,底层是链表结构和Set结构

TreeSet:

TreeSet有两种排序方法:

自然排序:(默认)

TreeSet 会调用集合元素的compareTo(Object obj) 方法来比较元素之间的大小关系,然后将集合元素按升序排列

定制排序:

如果试图把一个对象添加到TreeSet时,则该对象的类必须实现Comparable 接口。

实现Comparable的类必须实现compareTo(Object obj) 方法,两个对象即通过compareTo(Object obj) 方法的返回值来比较大小。

 

注意:

向TreeSet 中添加元素时,只有第一个元素无须比较compareTo()方法,后面添加的所有元素都会调用compareTo()方法进行比较。

因为只有相同类的两个实例才会比较大小,所以向TreeSet 中添加的应该是同一个类的对象

对于TreeSet 集合而言,它判断两个对象是否相等的唯一标准是:两个对象通过compareTo(Object obj) 方法比较返回值

当需要把一个对象放入TreeSet 中,重写该对象对应的equals() 方法时,应保证该方法与compareTo(Object obj) 方法有一致的结果:如果两个对象通过equals() 方法比较返回true,则通过compareTo(Object obj) 方法比较应返回0

 

代码:

public class TestTreeSet {

public static void main(String[] args) {

TreeSet<TestTreeSet_test> t = new TreeSet<TestTreeSet_test>();

//添加对象

t.add(new TestTreeSet_test(1,2));

t.add(new TestTreeSet_test(0,9));

t.add(new TestTreeSet_test(3,4));

System.out.println(t);

 

TreeSet<Integer> t2 = new TreeSet<Integer>();

//添加int数据

t2.add(2);

t2.add(5);

t2.add(3);

t2.add(9);

t2.add(6);

System.out.println(t2);

}

}

class TestTreeSet_test implements Comparable<Object>{

intx,y;

public TestTreeSet_test() {}

public TestTreeSet_test(intx,inty) {

this.x = x;

this.y = y;

}

@Override

public int compareTo(Object o) {

if(o instanceof TestTreeSet_test) {

TestTreeSet_test t = (TestTreeSet_test) o;

if(this.x>t.x) {

return 1;

}else {

return -1;

}

}

return 0;

}

@Override

public String toString() {

return"x="+x+" y="+y;

}

}

三. Map接口:请待下回