9 集合
2016-02-02 23:47
459 查看
collection接口
collection 接口方法
collection 迭代器
List接口
List接口的实现类
ArrayList
LinkedList
Vector
Set接口
Set接口的实现类
HashSet依靠equals和HashCode的方法共同作用
TreeSet
set集合中的equals和hashCode 转
创建String对象过程的内存分配转
Tips
小案例使用LinkedList实现洗牌
—-| Collection 单列集合 的根接口
——-| List 如果是实现了List接口的集合类,该集合类具备的特点:有序,可重复。
——-| Set 如果是实现了Set接口的集合类,该集合类具备的特点: 无序,不可重复。
toArray()
iterator()
迭代器的作用:就是用于抓取集合中的元素。
迭代器的方法:
NoSuchElementException 没有元素的异常。
出现的原因: 没有元素可以被迭代了。。。
List接口中特有的方法具备的特点: 操作的方法都存在索引值。
只有List接口下面的集合类才具备索引值。其他接口下面的集合类都没有索引值。
listIterator()
ListIterator特有的方法:
迭代器注意事项
迭代器在变量元素的时候要注意事项: 在迭代器迭代元素的过程中,不允许使用集合对象改变集合中的元素个数,如果需要添加或者删除只能使用迭代器的方法进行操作。
如果使用过了集合对象改变集合中元素个数那么就会出现ConcurrentModificationException异常。
迭代元素的过程中: 迭代器创建到使用结束的时间。
错误案例:
正确使用:必须通过迭代器添加元素,因为迭代器指针会跳过通过迭代器添加的元素
—————| ArrayList ArrayList 底层是维护了一个Object数组实现的。 特点: 查询速度快,增删慢。
—————| LinkedList LinkedList 底层是使用了链表数据结构实现的, 特点: 查询速度慢,增删快。
—————| Vector(了解即可) 底层也是维护了一个Object的数组实现的,实现与ArrayList是一样的,但是Vector是线程安全的,操作效率低。
——| Set 如果是实现了Set接口的集合类,具备的特点: 无序,不可重复。
ArrayList:
ArrayList 底层是维护了一个Object数组实现的, 特点: 查询速度快,增删慢。
什么时候使用ArrayList: 如果目前的数据是查询比较多,增删比较少的时候,那么就使用ArrayList存储这批数据。
笔试题目: 使用ArrayList无参的构造函数创建一个对象时, 默认的容量是多少? 如果长度不够使用时又自增增长多少?
ArrayList底层是维护了一个Object数组实现的,使用无参构造函数时,Object数组默认的容量是10,当长度不够时,自动增长0.5倍。
特有的方法:
LinkedList实现数据结构
1:栈 (1.6) : 主要是用于实现堆栈数据结构的存储方式。
2:队列(双端队列1.5): 主要是为了让你们可以使用LinkedList模拟队列数据结构的存储方式。
返回逆序的迭代器对象
descendingIterator() 返回逆序的迭代器对象
相同点: ArrayList与Vector底层都是使用了Object数组实现的。
不同点:
1. ArrayList是线程不同步的,操作效率高。
Vector是线程同步的,操作效率低。
2. ArrayList是JDK1.2出现,Vector是jdk1.0的时候出现的。
无序: 添加元素 的顺序与元素出来的顺序是不一致的。
接口方法和collection 一致
实现原理
往Haset添加元素的时候,HashSet会先调用元素的hashCode方法得到元素的哈希值 ,然后通过元素的哈希值经过移位等运算,就可以算出该元素在哈希表中的存储位置。
情况1: 如果算出元素存储的位置目前没有任何元素存储,那么该元素可以直接存储到该位置上。
情况2: 如果算出该元素的存储位置目前已经存在有其他的元素了,那么会调用该元素的equals方法与该位置的元素再比较一次,如果equals返回的是true,那么该元素与这个位置上的元素就视为重复元素,不允许添加,如果equals方法返回的是false,那么该元素运行添加。
HashSet注意事项
HashSet是根据hashcode算出来的数值然后在哈希表中找相应的位置,如果某类是根据一个变量返回哈希值,如果修改了这个值,会影响remove的判断,如下
往TreeSet添加元素的时候,如果元素本身具备了自然顺序的特性,那么就按照元素自然顺序的特性进行排序存储。
往TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,那么该元素所属的类必须要实现Comparable接口,把元素的比较规则定义在compareTo(T o)方法上。
如果比较元素的时候,compareTo方法返回的是0,那么该元素就被视为重复元素,不允许添加.(注意:TreeSet与HashCode、equals方法是没有任何关系。)
往TreeSet添加元素的时候, 如果元素本身没有具备自然顺序 的特性,而元素所属的类也没有实现Comparable接口,那么必须要在创建TreeSet的时候传入一个比较器。
往TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,而元素所属的类已经实现了Comparable接口, 在创建TreeSet对象的时候也传入了比较器, 那么是以比较器的比较规则优先使用。
如何自定义定义比较器: 自定义一个类实现Comparator接口即可,把元素与元素之间的比较规则定义在compare方法内即可。
自定义比较器的格式 :
推荐使用:使用比较器(Comparator)。
TreeSet是可以对字符串进行排序 的, 因为字符串已经实现了Comparable接口。字符串的比较规则:
情况一: 对应位置有不同的字符出现, 就比较的就是对应位置不同的字符。
情况 二:对应位置上 的字符都一样,比较的就是字符串的长度。
Java 对equals方法和hashCode方法是这样规定的:
如果两个对象相同(使用equals比较,所以如果改写equals方法,一般也要改写hashCode方法),那么它们的hashCode值一定要相同;
如果两个对象的的hashCode相同,它们并不一定相同。(因为对于散列表来说每个位置是可能重复的)
hashCode和equals的比较:
equals的方法是给用户调用的,如果你想判断两个对象是否相等,你可以重写equals方法
hashCode方法一般不会让用户调用,比如hashmap中,由于Key是不可以重复的(equals和hashCode只要有一个不等即使不重复),它在判断key是不是重复的时候就判断了hashcode方法,而且也用到了equals方法。
在class文件被JVM装载到内存中,JVM会创建一块String Pool,当执行这句话时,JVM首先在Pool中查看是否存在相同的字符串(使用equals比较),如果存在该对象,则不用创建新的字符串,而直接使用String Pool中已存在的对象“abc,然后将引用s指向String Pool中创建的对象。
String s = new String(“abc”);
首先在Pool中查看是否存在对象”abc”, 没有则创建,然后又在Heap创建一个新的对象,并赋给s.
如果Pool中存在,则不创建,然后在Heap中创建的对象.
即New一个String对象 相当于创建了两个对象(常量池中一个 heap中一个)
注意:new 两个String对象,即使内容相同,内存地址也不相同
outer: while(true)
…
break outer;
indexof 返回的是第一个
刚刚初始化的迭代器是不指向任何元素的
Random random = new random();
Random.nextint(大小) 这个范围不用减1,范围是0-大小
字符串转Int
Integer.parseInt
collection 接口方法
collection 迭代器
List接口
List接口的实现类
ArrayList
LinkedList
Vector
Set接口
Set接口的实现类
HashSet依靠equals和HashCode的方法共同作用
TreeSet
set集合中的equals和hashCode 转
创建String对象过程的内存分配转
Tips
小案例使用LinkedList实现洗牌
collection接口
集合接口的继承关系:—-| Collection 单列集合 的根接口
——-| List 如果是实现了List接口的集合类,该集合类具备的特点:有序,可重复。
——-| Set 如果是实现了Set接口的集合类,该集合类具备的特点: 无序,不可重复。
collection 接口方法
//增 add(E e); addAll(Collection<? extends E> c); //删 clear(); remove(Object o); removeAll(Collection<?> c); //交集 retainAll(Collection<?> c); //判断 contains(Object o); containsAll (Collection<?> c); equals(Object o); isEmpty(); //迭代器 iteratior(); //大小 size(); //转换为数组 toArray();
collection 迭代器
Collection—迭代的方法:toArray()
iterator()
迭代器的作用:就是用于抓取集合中的元素。
迭代器的方法:
hasNext() 问是否有元素可遍历。如果有元素可以遍历,返回true,否则返回false 。 next() 获取元素... remove() 移除迭代器最后一次返回 的元素。
NoSuchElementException 没有元素的异常。
出现的原因: 没有元素可以被迭代了。。。
List接口
List接口中特有方法:添加 add(int index, E element) addAll(int index, Collection<? extends E> c) 获取: get(int index) indexOf(Object o) lastIndexOf(Object o) subList(int fromIndex, int toIndex) 修改: set(int index, E element) 迭代 listIterator()
List接口中特有的方法具备的特点: 操作的方法都存在索引值。
只有List接口下面的集合类才具备索引值。其他接口下面的集合类都没有索引值。
listIterator()
ListIterator特有的方法:
hasPrevious() 判断是否存在上一个元素。 previous() 当前指针先向上移动一个单位,然后再取出当前指针指向的元素。 next(); 先取出当前指针指向的元素,然后指针向下移动一个单位。 add(E e) 把当前有元素插入到当前指针指向的位置上。 set(E e) 替换迭代器最后一次返回的元素。
迭代器注意事项
迭代器在变量元素的时候要注意事项: 在迭代器迭代元素的过程中,不允许使用集合对象改变集合中的元素个数,如果需要添加或者删除只能使用迭代器的方法进行操作。
如果使用过了集合对象改变集合中元素个数那么就会出现ConcurrentModificationException异常。
迭代元素的过程中: 迭代器创建到使用结束的时间。
错误案例:
ListIterator it = list.listIterator(); //获取到迭代器 list.add("aa");//改变元素个数,将会出现错误 it.next();
while(it.hasNext()){ System.out.print(it.next()+","); list.add("aa"); // add方法是把元素添加到集合的末尾处的。
正确使用:必须通过迭代器添加元素,因为迭代器指针会跳过通过迭代器添加的元素
while(it.hasNext()){ System.out.print(it.next()+","); it.add("aa"); // 把元素添加到当前指针指向位置 } //最后集合元素的输出 [张三, aa, 李四, aa, 王五, aa]
List接口的实现类
——| List 如果是实现了List接口的集合类,具备的特点: 有序,可重复。—————| ArrayList ArrayList 底层是维护了一个Object数组实现的。 特点: 查询速度快,增删慢。
—————| LinkedList LinkedList 底层是使用了链表数据结构实现的, 特点: 查询速度慢,增删快。
—————| Vector(了解即可) 底层也是维护了一个Object的数组实现的,实现与ArrayList是一样的,但是Vector是线程安全的,操作效率低。
——| Set 如果是实现了Set接口的集合类,具备的特点: 无序,不可重复。
ArrayList
List的实现类主要有三种:ArrayList LinkedList 和 Vector(不重要)ArrayList:
ArrayList 底层是维护了一个Object数组实现的, 特点: 查询速度快,增删慢。
什么时候使用ArrayList: 如果目前的数据是查询比较多,增删比较少的时候,那么就使用ArrayList存储这批数据。
笔试题目: 使用ArrayList无参的构造函数创建一个对象时, 默认的容量是多少? 如果长度不够使用时又自增增长多少?
ArrayList底层是维护了一个Object数组实现的,使用无参构造函数时,Object数组默认的容量是10,当长度不够时,自动增长0.5倍。
特有的方法:
ensureCapacity(int minCapaci上ty)//确保它至少能够容纳最小容量参数所指定的元素数 trimToSize()
LinkedList
特有方法:addFirst(E e) addLast(E e) getFirst() getLast() removeFirst() removeLast()
LinkedList实现数据结构
1:栈 (1.6) : 主要是用于实现堆栈数据结构的存储方式。
先进后出 push() pop()
2:队列(双端队列1.5): 主要是为了让你们可以使用LinkedList模拟队列数据结构的存储方式。
先进先出 offer() poll()
返回逆序的迭代器对象
descendingIterator() 返回逆序的迭代器对象
Vector
笔试题: 说出ArrayLsit与Vector的区别?相同点: ArrayList与Vector底层都是使用了Object数组实现的。
不同点:
1. ArrayList是线程不同步的,操作效率高。
Vector是线程同步的,操作效率低。
2. ArrayList是JDK1.2出现,Vector是jdk1.0的时候出现的。
Set接口
Set接口是无序的无序: 添加元素 的顺序与元素出来的顺序是不一致的。
接口方法和collection 一致
Set接口的实现类
HashSet(依靠equals和HashCode的方法共同作用)
底层是使用了哈希表来支持的,特点: 存取速度快.实现原理
往Haset添加元素的时候,HashSet会先调用元素的hashCode方法得到元素的哈希值 ,然后通过元素的哈希值经过移位等运算,就可以算出该元素在哈希表中的存储位置。
情况1: 如果算出元素存储的位置目前没有任何元素存储,那么该元素可以直接存储到该位置上。
情况2: 如果算出该元素的存储位置目前已经存在有其他的元素了,那么会调用该元素的equals方法与该位置的元素再比较一次,如果equals返回的是true,那么该元素与这个位置上的元素就视为重复元素,不允许添加,如果equals方法返回的是false,那么该元素运行添加。
HashSet注意事项
HashSet是根据hashcode算出来的数值然后在哈希表中找相应的位置,如果某类是根据一个变量返回哈希值,如果修改了这个值,会影响remove的判断,如下
@Override public int hashCode() { return this.name.hashCode(); } @Override public boolean equals(Object obj) { Book b = (Book)obj; return this.name.equals(b.name); }
public static void main(String[] args) { //不允许重复的书名存在。 HashSet<Book> books = new HashSet<Book>(); books.add(new Book("深入javaweb",34)); books.add(new Book("java神书",78)); //修改书名 Iterator<Book> it = books.iterator(); while(it.hasNext()){ Book b = it.next(); if(b.name.equals("java神书")){ b.name = "java编程思想"; } } //为什么修改名字之后不能删除了呢? books.remove(new Book("java神书",78)); System.out.println("集合的元素:"+ books); }
TreeSet
treeSet要注意的事项:往TreeSet添加元素的时候,如果元素本身具备了自然顺序的特性,那么就按照元素自然顺序的特性进行排序存储。
往TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,那么该元素所属的类必须要实现Comparable接口,把元素的比较规则定义在compareTo(T o)方法上。
如果比较元素的时候,compareTo方法返回的是0,那么该元素就被视为重复元素,不允许添加.(注意:TreeSet与HashCode、equals方法是没有任何关系。)
往TreeSet添加元素的时候, 如果元素本身没有具备自然顺序 的特性,而元素所属的类也没有实现Comparable接口,那么必须要在创建TreeSet的时候传入一个比较器。
往TreeSet添加元素的时候,如果元素本身不具备自然顺序的特性,而元素所属的类已经实现了Comparable接口, 在创建TreeSet对象的时候也传入了比较器, 那么是以比较器的比较规则优先使用。
如何自定义定义比较器: 自定义一个类实现Comparator接口即可,把元素与元素之间的比较规则定义在compare方法内即可。
自定义比较器的格式 :
class 类名 implements Comparator{ }
推荐使用:使用比较器(Comparator)。
TreeSet是可以对字符串进行排序 的, 因为字符串已经实现了Comparable接口。字符串的比较规则:
情况一: 对应位置有不同的字符出现, 就比较的就是对应位置不同的字符。
情况 二:对应位置上 的字符都一样,比较的就是字符串的长度。
set集合中的equals和hashCode (转)
hashCode默认是计算出对象的内存地址,可以自己改写,例如String类就改写了Java 对equals方法和hashCode方法是这样规定的:
如果两个对象相同(使用equals比较,所以如果改写equals方法,一般也要改写hashCode方法),那么它们的hashCode值一定要相同;
如果两个对象的的hashCode相同,它们并不一定相同。(因为对于散列表来说每个位置是可能重复的)
hashCode和equals的比较:
equals的方法是给用户调用的,如果你想判断两个对象是否相等,你可以重写equals方法
hashCode方法一般不会让用户调用,比如hashmap中,由于Key是不可以重复的(equals和hashCode只要有一个不等即使不重复),它在判断key是不是重复的时候就判断了hashcode方法,而且也用到了equals方法。
创建String对象过程的内存分配(转)
String s = “abc”;在class文件被JVM装载到内存中,JVM会创建一块String Pool,当执行这句话时,JVM首先在Pool中查看是否存在相同的字符串(使用equals比较),如果存在该对象,则不用创建新的字符串,而直接使用String Pool中已存在的对象“abc,然后将引用s指向String Pool中创建的对象。
String s = new String(“abc”);
首先在Pool中查看是否存在对象”abc”, 没有则创建,然后又在Heap创建一个新的对象,并赋给s.
如果Pool中存在,则不创建,然后在Heap中创建的对象.
即New一个String对象 相当于创建了两个对象(常量池中一个 heap中一个)
注意:new 两个String对象,即使内容相同,内存地址也不相同
Tips
循环可以加标号outer: while(true)
…
break outer;
indexof 返回的是第一个
刚刚初始化的迭代器是不指向任何元素的
Random random = new random();
Random.nextint(大小) 这个范围不用减1,范围是0-大小
字符串转Int
Integer.parseInt
小案例:使用LinkedList实现洗牌
package cn.itcast.list; import java.util.LinkedList; import java.util.Random; /* 需求: 使用LinkedList存储一副扑克牌,然后实现洗牌功能。 */ //扑克类 class Poker{ String color; //花色 String num; //点数 public Poker(String color, String num) { super(); this.color = color; this.num = num; } @Override public String toString() { return "{"+color+num+"}"; } } public class Demo2 { public static void main(String[] args) { LinkedList pokers = createPoker(); shufflePoker(pokers); showPoker(pokers); } //洗牌的功能 public static void shufflePoker(LinkedList pokers){ //创建随机数对象 Random random = new Random(); for(int i = 0 ; i <100; i++){ //随机产生两个索引值 int index1 = random.nextInt(pokers.size()); int index2 = random.nextInt(pokers.size()); //根据索引值取出两张牌,然后交换两张牌的顺序 Poker poker1 = (Poker) pokers.get(index1); Poker poker2 = (Poker) pokers.get(index2); pokers.set(index1, poker2); pokers.set(index2, poker1); } } //显示扑克牌 public static void showPoker(LinkedList pokers){ for(int i = 0 ; i<pokers.size() ; i++){ System.out.print(pokers.get(i)); //换行 if(i%10==9){ System.out.println(); } } } //生成扑克牌的方法 public static LinkedList createPoker(){ //该集合用于存储扑克对象。 LinkedList list = new LinkedList(); //定义数组存储所有的花色与点数 String[] colors = {"黑桃","红桃","梅花","方块"}; String[] nums = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"}; for(int i = 0 ; i < nums.length ; i++){ for(int j = 0 ; j<colors.length ; j++){ list.add(new Poker(colors[j], nums[i])); } } return list; } }
相关文章推荐
- 如何发现war工程运行期间是否有僵死的servlet线程
- 【推荐】大规模的自然场景文字检测与识别数据库
- 计算机网络3--计算机网络结构
- 为啥要用模板引擎呢?
- ActiveMQ 集群(1)
- MySQL 存储过程 批量插入
- 贝叶斯的路——概率论迷思
- js的一些总结
- 利用sqoop从mysql向hbase导数据(拼接mysql多字段做为hbase rowkey)
- tabhost使用
- 命令行下JSON处理工具:jq
- 解密:华为的敏捷网络是SDN吗
- Gulp.js深入讲解
- JavaEE 7中的EJB
- CentOS7_装机软件推荐
- 4.MVC框架开发(母版页的应用、按钮导致的Action处理、从界面向控制器传数据和HtmlHelper控件的实现(注册的实现))
- package.json for npm中依赖外部组件时常用的版本符号含义
- 关于Android开发中的证书和密钥等问题
- 一个游戏程序员的App移动互联网创业
- 个人笔记 asp 09 asp字符串转换