三大集合特点
来源:互联网 发布:淘宝水印怎么批量设置 编辑:程序博客网 时间:2024/04/30 07:14
一、Set集合,其主要实现类有HashSet、TreeSet。存放对象的引用,不允许有重复对象。
通过java的equals()方法判别。如果有特殊需求须重载equals()方法。
1、HashSet(),调用对象的hashCode()方法,获得哈希码,然后再集合中计算存放对象的位置。通过比较哈希码与equals()方法来判别是否重复。所以,重载了equals()方法同时也要重载hashCode()方法。
2、TreeSet(),继承ShortedSet接口,能够对集合中对象排序。默认排序方式是自然排序,但该方式只能对实现了Comparable接口的对象排序,java中对Integer、Byte、Double、Character、String等数值型和字符型对象都实现了该接口。
如果有特殊排序,须重载该接口下的compareTo()方法或通过Comparator接口的实现类构造集合。
二、List集合,其主要实现类有LinkedList、ArrayList,前者实现了链表结构,后者可代表大小可变的数组。List的特点是能够以线性方式储蓄对象,并允许存放重复对象。List能够利用Collections类的静态方法sort排序。sort(List list)自然排序;sort(List listm,Comparator comparator)客户化排序。
三、Map集合,其主要实现类有HashMap、TreeMap。Map对值没有唯一性要求,对健要求唯一,如果加入已有的健,原有的值对象将被覆盖。HashMap类按照哈希算法来存取键对象,可以重载equals()、hashCode()方法来比较键,但是两者必须一致。TreeMap,可自然排序,也可通过传递Comparator的实现类构造TreeMap。
(1)集合的由来?
我们学习的是Java – 面向对象 – 操作很多对象 – 存储 – 容器(数组和StringBuffer) – 数组
而数组的长度固定,所以不适合做变化的需求,Java就提供了集合供我们使用。
(2)集合和数组的区别?
A:长度区别
数组固定
集合可变
B:内容区别
数组可以是基本类型,也可以是引用类型
集合只能是引用类型
C:元素内容
数组只能存储同一种类型
集合可以存储不同类型(其实集合一般存储的也是同一种类型)
(3)集合的继承体系结构?
由于需求不同,Java就提供了不同的集合类。这多个集合类的数据结构不同,但是它们都是要提供存储和遍历功能的,
我们把它们的共性不断的向上提取,最终就形成了集合的继承体系结构图。
Collection:
|–List 有序(元素存入集合的顺序和取出的顺序一致),元素都有索引,而且元素可以重复。
|–ArrayList
|–Vector
|–LinkedList
|–Set 无序(存入和取出顺序有可能不一致),不可以存储重复元素。必须保证元素唯一性。
|–HashSet
|–TreeSet
Collection的功能:
A:添加功能
boolean add(Object obj):向集合中添加一个元素
boolean addAll(Collection c):向集合中添加一个集合的元素
B:删除功能
void clear():删除集合中的所有元素
boolean remove(Object obj):向集合中删除指定的元素
booleanremoveAll(Collection c):向集合中删除一个指定的集合元素
C:判断功能
boolean isEmpty():判断集合是否为空
boolean contains(Object obj):判断集合中是否存在指定的元素
boolean containsAll(Collection c):判断集合中是否存在指定的元素
D:遍历功能
Iterator iterator():就是用来获取集合中每一个元素
E:长度功能
int size():获取集合中的元素个数
F:交集功能
boolean retainAll(Collection c):判断两个集合中是否有相同的元素
G:转换功能
Object[] toArray():把集合变成数组
小练习:遍历集合中的元素,判断是否存在元素“hello”。
/* * 请遍历集合:也就是获取到集合中的每一个元素。 * 判断集合中是否存在"hello"这个元素. * 注意: * 在往集合中添加元素的时候,集合默认接收的是Object类型。 * 也就是说你开始存储字符串的时候,其实做了一个向上转型的操作。 * * 在获取元素的时候,默认还是以Object类型的返回。 * 但是,你明明知道这应该是String类型。 * 所以,如果你想使用String类型的特殊功能,就必须做向下转型。 * 如果仅仅是为了看结果,就不用。因为通过多态的形式,最终输出语句调用的是String类的toString() */public class CollectionDemo2 { public static void main(String[] args) { flag=true; //元素标记符, Collection c = new ArrayList(); //创建集合对象 // 添加元素 c.add("hello"); // String -- Object c.add("world"); c.add("java"); // 直接使用判断功能 // System.out.println("contains:"+c.contains("hello")); // System.out.println("c:" + c);//若存在,则会输出true // 遍历集合,获取到每一个元素,然后判断这个元素是否是hello // Object[] toArray():把集合变成数组。 Object[] objs = c.toArray(); for (int x = 0; x < objs.length; x++) { //将Object类型的数组强制转换为String类型 String s = (String) objs[x]; if(s.equals("hello")){ flag=true; //如果存在,就输出真,否则输出假 }else{ flag=false; } System.out.println(s + "***" + s.length()+"***"+flag); } }}
小练习:用迭代器遍历集合中的元素。
/* * 成员方法: * Object next():获取元素,并自动移动到下一个位置等待获取。 * boolean hasNext():判断迭代器中是否还有元素。 * NoSuchElementException:没有这样的元素异常。你已经获取到元素末尾了,你还要获取,已经没有元素了。所以报错了。 */public class IteratorDemo { public static void main(String[] args) { // 创建对象 Collection c = new ArrayList(); // 添加元素 c.add("hello"); c.add("world"); c.add("java"); // 方式1 // Object[] objs = c.toArray(); // for (int x = 0; x < objs.length; x++) { // String s = (String) objs[x]; // System.out.println(s); // }// 方式2 // Iterator iterator():就是用来获取集合中每一个元素。 // 通过集合对象获取迭代器对象 Iterator it = c.iterator();// 这是返回的是Iterator的子类对象,多态 while (it.hasNext()) { // System.out.println(it.next()); String s = (String) it.next(); System.out.println(s); } } }
list接口
List本身是Collection接口的子接口,具备Collection的所有方法。现在学习list体系特有的共性方法,查阅方法发现List的特有方法都有索引,这是该集合最大的特点。
1)List特有功能:
A:添加功能
void add(int index,Object obj):在指定位置添加元素
B:删除功能
Object remove(int index):根据指定索引删除元素,并把删除的元素返回
C:修改功能
Object set(int index,Object obj):把指定索引位置的元素修改为指定的值,返回修改前的值。
D:获取功能
Object get(int index):返回指定元素在集合中第一次出现的索引
int indexOf(Object obj):获取指定位置的元素,如果该元素不存在返回-1;所以,通过-1,可以判断一个元素是否存在 int lastIndexOf(Object obj):反向索引指定元素的位置
List subList(start,end):获取子列表
ListIterator listIterator():列表迭代器(List集合特有的迭代器)
2)List的遍历方式
A:Iterator 迭代器
B:ListIterator迭代器(了解)
C:普通for(和list的get方法使用)
3)ListIterator迭代器
A:是Iterator的子接口。
B:有自己的特有功能,可以逆向遍历数据,但是需要先正向遍历。一般不用。
/* * ListIterator listIterator():列表迭代器 * * boolean hasNext() * Object next() * * 特有功能: * boolean hasPrevious() * Object previous() * * 虽然,可以逆向遍历,但是,要求先正向遍历,然后才能逆向遍历。 */public class ListDemo5 { public static void main(String[] args) { // 创建集合对象 List list = new ArrayList(); // 添加元素 list.add("hello"); list.add("world"); list.add("java"); // 遍历 ListIterator lit = list.listIterator(); while (lit.hasNext()) { String s = (String) lit.next(); System.out.println(s); } System.out.println("----------------"); // System.out.println(lit.previous()); // System.out.println(lit.previous()); // System.out.println(lit.previous()); // // NoSuchElementException // System.out.println(lit.previous()); // 逆向遍历 while (lit.hasPrevious()) { String s = (String) lit.previous(); System.out.println(s); } }}
4)面试题:并发修改异常
A:并发修改异常的产生原因:用迭代器遍历集合,用集合去操作集合。
B:解决方案:a:使用集合操作。
b:使用列表迭代器操作。
代码如下:
import java.util.ArrayList;import java.util.List;import java.util.ListIterator;/* * ListIterator listIterator():列表迭代器 * * public interface ListIterator extends Iterator * * 面试题:ConcurrentModificationException:并发修改异常。 * 这是个什么异常,怎么产生的,怎么解决的? * 怎么产生: * 当我们通过迭代器迭代元素的过程中,又通过集合去添加了元素。这种情况是不允许的。 * 因为迭代器是依赖于集合存在的,如果集合发生改变,迭代器也应该相应的发生改变。 * 而我们目前看到的确实,迭代器没变,集合变了。所以,报出了一个并发修改异常。 * * 注意问题:通过迭代器遍历集合的时候,是不能通过集合去操作(添加,删除)。 * 那么,我们可不可以这样理解呢? * A:全部通过迭代器操作:元素是添加到刚遍历的那个元素后面。 * 通过迭代器迭代的时候,可以通过迭代器对集合进行操作。 * B:全部通过集合操作:元素是添加到最后的。 * 通过集合普通for遍历的时候,可以通过集合去操作。 */public class ListDemo4 { public static void main(String[] args) { // 创建集合对象 List list = new ArrayList(); // 添加元素 list.add("hello"); list.add("world"); list.add("java"); // 迭代器 // Iterator it = list.iterator(); // while (it.hasNext()) { // String s = (String) it.next(); // System.out.println(s); // } // System.out.println("-----------"); // 需求:请遍历集合,判断其中是否有"hello"这个元素,如果有,就再添加一个元素:"IOS" // Iterator it = list.iterator(); // while (it.hasNext()) { // String s = (String) it.next(); // if ("hello".equals(s)) { // list.add("IOS"); // // it = list.iterator();//这样从原理是可以解决的,但是它会引起另外一个问题。 // } // } // System.out.println("list:" + list); // System.out.println("-----------"); // 完全通过集合实现 // for (int x = 0; x < list.size(); x++) { // String s = (String) list.get(x); // if ("hello".equals(s)) { // list.add("IOS"); // } // } // System.out.println("list:"+list); // System.out.println("-----------"); // 遍历 ListIterator lit = list.listIterator(); while (lit.hasNext()) { String s = (String) lit.next(); if ("hello".equals(s)) { lit.add("IOS"); } } System.out.println("list:" + list); }}
5)List:
|–ArrayList:底层数据结构是数组,线程不安全(即不同步),它的出现替代了Vector,增删的效率很慢,但是查询的效率很高。
|–Vector:底层数据结构是数组,线程安全,无论增删还是查询都非常慢。
|–LinkedList:底层是链表,线程不安全,对元素的增删的操作效率很高,查询效率低。
ArrayList的小练习:
需求:我现在用ArrayList存储多个字符串元素。
比如说数据如下:hello,world,java,hello,.net,java,php,IOS,java,android
我要求你写程序,实现去除重复元素。也就是说结果是:hello,world,java,.net,php,IOS,android
5)List: |--ArrayList:底层数据结构是数组,线程不安全(即不同步),它的出现替代了Vector,增删的效率很慢,但是查询的效率很高。 |--Vector:底层数据结构是数组,线程安全,无论增删还是查询都非常慢。 |--LinkedList:底层是链表,线程不安全,对元素的增删的操作效率很高,查询效率低。ArrayList的小练习:需求:我现在用ArrayList存储多个字符串元素。 比如说数据如下:hello,world,java,hello,.net,java,php,IOS,java,android 我要求你写程序,实现去除重复元素。也就是说结果是:hello,world,java,.net,php,IOS,android
方法二:
/* * 在同一个集合上操作:双层循环实现 * 第一方式没有问题,第二种可能有问题。 * 但是,第二种的问题也是可以解决的? * 怎么解决呢? * 把每次删除掉元素的那个位置,在回来比较一次即可。 */public class ArrayListTest2 { public static void main(String[] args) { // 创建旧集合,并添加元素 ArrayList array = new ArrayList(); array.add("hello"); array.add("world"); array.add("java"); array.add("hello"); array.add(".net"); array.add("java"); array.add("java"); array.add("java"); array.add("php"); array.add("IOS"); array.add("java"); array.add("android"); // 这下面的代码和选择排序类似。理解即可。最好通过断点看过程。 for (int x = 0; x < array.size() - 1; x++) { for (int y = x + 1; y < array.size(); y++) { if (array.get(y).equals(array.get(x))) { array.remove(y); y--; } } } // 遍历 Iterator it = array.iterator(); while (it.hasNext()) { String s = (String) it.next(); System.out.println(s); } }}
下面是一个面试题:用ArrayList存储学生,如何去除重复的元素?
“`
import java.util.ArrayList;
import java.util.Iterator;
/*
* ArrayList如果存储的是学生,那么,怎么去除重复元素呢?
* 问题:如何知道学生是重复的。
* 需求:如果学生的姓名和年龄相同,我就认为是同一个学生。即重复值。
*
* 通过简单分析,我们估计是判断那里出问题了。
* 怎么办呢?
* 看判断的方法。
* 而我们又知道,判断的方法是API提供的。不是自己的写的。
* 看源码,看底层到底怎么实现的。
* 通过看源码,我们发现,底层依赖的是equals()。
* 由于学生类中,我们并没有equals()方法,所以,默认用的是Object的方法。
* 而Object类的方法,默认比较的是地址值。
* 由于学生对象都是new出来的,地址值肯定不一样,所以从这个角度考虑结论是正确的。
* 但是不符合我们的需求。
* 肿么办?
* 重写equals(),让他按照我们的需要来比较。
*/
//标准学生类
public class Student {
//定义两个成员变量
private String name;
private int age;
public Student() {}public Student(String name, int age) { this.name = name; this.age = age;}public String getName() { return name;}public void setName(String name) { this.name = name;}public int getAge() { return age;}public void setAge(int age) { this.age = age;} //重写equals方法@Overridepublic boolean equals(Object obj) { // 提高效率 if (this == obj) { return true; } // 提高健壮性 if (!(obj instanceof Student)) { return false; } // 向下转换 Student s = (Student) obj; return this.name.equals(s.name) && this.age == s.age;}
}
public class ArrayListTest3 {
public static void main(String[] args) {
ArrayList array = new ArrayList();
Student s1 = new Student("301宿舍--笨笨", 22); Student s2 = new Student("301宿舍--姗姗", 23); Student s3 = new Student("301宿舍--姗姗", 30); Student s4 = new Student("301宿舍--红红", 20); Student s5 = new Student("301宿舍--红红", 20); Student s6 = new Student("301宿舍--蛋蛋", 24); Student s7 = new Student("301宿舍--媛媛", 22); Student s8 = new Student("301宿舍--歪歪", 23); array.add(s1); array.add(s2); array.add(s3); array.add(s4); array.add(s5); array.add(s6); // 创建新集合 ArrayList array2 = new ArrayList(); // 遍历旧集合,获取到每一个元素 Iterator it = array.iterator(); while (it.hasNext()) { Student s = (Student) it.next(); // 在新集合中判断,看是否存在这个元素 if (!array2.contains(s)) { // 如果s不再array2中存在,就添加 array2.add(s); } } // array2就是没有重复元素的集合。 // 遍历array2 for (int x = 0; x < array2.size(); x++) { Student s = (Student) array2.get(x); System.out.println(s.getName() + "***" + s.getAge()); }}
}
“`
- 三大集合特点
- Java三大特点
- 技术人员的三大特点
- 面向对象三大特点
- SAP HANA 三大特点
- 面向对象 三大特点
- OO技术三大特点
- SAP HANA 三大特点
- JAVA三大集合
- 面向对象编程(OOP)三大特点
- ARM处理器的三大特点
- 嵌入式开发管理的三大特点
- 面对对象的三大特点
- 面向对象三大特点心得理解.......
- 面向对象的三大特点
- 面向对象的三大特点
- OC面向对象的三大特点
- 面向对象的三大特点
- 【图论】【贪心】[coci CONTEST #1 2014.10.18]MAFIJA
- 互联网券商行业公司
- 数据结构之顺序查找java实现
- uva 12167 Proving Equivalences(强连通分量 + 缩点)
- jaxb转化xml笔记
- 三大集合特点
- Java中的类
- Pro Git(中文版)
- Netty5入门学习笔记004-使用Netty传输POJO对象
- POJ 2431 Expedition (汽车加油问题,STL_优先队列+贪心) (挑战程序P76)
- JS中this的四种调用模式
- ATMSystem
- 原码, 反码, 补码 详解
- 用动态规划的方法解决LCS(最长公共子序列)的问题