标签:排列 动态 直接 包装 lifo sync 顺序存储 == 内容
数组不是面向对象的,存在明显的缺陷,集合弥补了数组的缺点,比数组更灵活更实用,而且不同的集合框架类可适用不同场合。如下:
Collection和Map,是集合框架的根接口。
Set: 接口 ---实现类: HashSet、LinkedHashSet
Set 的子接口SortedSet接口---实现类:TreeSet
List: 接口---实现类: LinkedList,Vector,ArrayList
Collection下面有两个常见的集合类型:
* java.util.List:可重复集,并且有序
* java.util.Set:不可重复集
* Set集合不可以存放重复元素,而元素是否重复是依靠元素
* 自身equals比较的结果而定。
Collection c = new ArrayList();
//HashSet是最常用的Set集合实现类
Collection c = new HashSet();
boolean add(E e)
向当前集合中添加给定元素,成功添加后则返回true
c.add("one");
c.add("two");
c.add("three");
c.add("four");
c.add("five");
c.add("five");//Set集合相同元素不能放进去2次
System.out.println(c);
int size()
返回当前集合的元素个数
int size = c.size();
boolean isEmpty()
判断当前集合是否为一个空集
集合不含有任何元素(size=0)
boolean isEmpty = c.isEmpty();
清空集合元素
c.clear();
删除集合元素
boolean remove(E e)
从集合中删除给定元素,删除的是集合中与给定元素equals
比较为true的元素。
Collection c = new ArrayList();
c.add(new Point(1,2));
c.add(new Point(3,4));
c.add(new Point(5,6));
c.add(new Point(7,8));
c.add(new Point(1,2));
System.out.println(c);// [(1,2), (3,4), (5,6), (7,8), (1,2)]
Point p = new Point(1,2); c.remove(p);
System.out.println(c);// [(3,4), (5,6), (7,8), (1,2)]
Collection c1 = new ArrayList();
c1.add("java");
c1.add("c++");
c1.add("c");
System.out.println(c1);//[java, c++, c]
Collection c2 = new HashSet();
c2.add("android");
c2.add("ios");
c2.add("java");
System.out.println(c2);//[java, android, ios]
/*
* addAll将给定集合中的所有元素添加到当前
* 集合中
*/
c1.addAll(c2);
System.out.println(c1);//[java, c++, c, java, android, ios]
Collection c3 = new ArrayList();
c3.add("c++");
c3.add("android");
//c3.add("php");
/*
* boolean contains(E e)
* 判断当前集合是否包含给定元素,判断也是根据元素
* equals比较的。
*
* boolean containsAll(Collection c)
* 判断当前集合是否包含给定集合的所有元素。
*/
boolean contains = c1.contains("java");
System.out.println("包含:"+contains);//包含:true
contains = c1.containsAll(c3);
System.out.println("全包含:"+contains);//全包含:true
/*
* 删除当前集合中与给定集合的共有元素(删交集)
*/
c1.removeAll(c3);
System.out.println(c1);//[java, c, java, ios]
集合只能存放引用类型元素,并且保存的也是元素的引用(地址)
遍历集合元素
Collection提供了统一的遍历集合元素的操作:迭代器模式
Iterator iterator()
该方法会返回一个用于遍历该集合的迭代器,使用这个迭代器 便可以遍历当前集合元素
java.util.Iterator接口
它是所有迭代器的顶级接口,不同的集合都实现了一个用于遍历 自身元素的迭代器实现类。
迭代器遍历集合遵循的原则为:问,取,删 。其中删除元素不是遍历过程中的必要操作。
Collection c = new ArrayList();
c.add("one");
c.add("#");
c.add("two");
c.add("#");
c.add("three");
c.add("#");
c.add("four");
c.add("#");
c.add("five");
System.out.println(c);
//获取迭代器
Iterator it = c.iterator();
/*
* boolean hasNext()
* 判断集合是否还有下一个元素可以迭代
*/
while(it.hasNext()) {
/*
* E next()
* 获取集合下一个元素
*/
String str = (String)it.next();
System.out.println(str);
if("#".equals(str)) {
/*
* 迭代器要求在遍历的过程中不得使用集合
* 的方法增删元素,否则遍历时会抛出异常
*/
//c.remove(str);
/*
* 迭代器也提供了remove方法,删除是通过
* next方法取出的元素。
*/
it.remove();
}
}
System.out.println(c);
增强for循环:
JDK5之后推出了一个特性:增强for循环 也称为新循环,for each.
新循环不是用来取代传统for循环的操作,而仅用来遍历集合 或数组使用。
编译器会将新循环遍历集合改为迭代器遍历 所以在遍历的过程中不能通过集合的方法增删元素
底层是Object数组,所以ArrayList具有数组的查询速度快的优点以及增删速度慢的缺点。
而在LinkedList的底层是一种双向循环链表。在此链表上每一个数据节点都由三部分组成:前指针(指向前面的节点的位置),数据,后指针(指向后面的节点的位置)。最后一个节点的后指针指向第一个节点的前指针,形成一个循环。
双向循环链表的查询效率低但是增删效率高。
ArrayList和LinkedList在用法上没有区别,但是在功能上还是有区别的。
实现机制:ArrayList.ensureCapacity(int minCapacity)
首先得到当前elementData 属性的长度oldCapacity。
然后通过判断oldCapacity和minCapacity参数谁大来决定是否需要扩容, 如果minCapacity大于 oldCapacity,那么我们就对当前的List对象进行扩容。 扩容的的策略为:取(oldCapacity * 3)/2 + 1和minCapacity之间更大的那个。然后使用数组拷 贝的方法,把以前存放的数据转移到新的数组对象中 如果minCapacity不大于oldCapacity那么就不进行扩容。
LinkedList是采用双向循环链表实现的。
利用LinkedList实现栈(stack)、队列(queue)、双向队列(double-ended queue )。 它具有方法addFirst()、addLast()、getFirst()、getLast()、removeFirst()、removeLast()等。
经常用在增删操作较多而查询操作很少的情况下:
队列和堆栈。
队列:先进先出的数据结构。
栈:后进先出的数据结构。
注意:使用栈的时候一定不能提供方法让不是最后一个元素的元素获得出栈的机会。
队列(Queue)是限定所有的插入只能在表的一端进行,而所有的删除都在表的另一端进行的线性表。
表中允许插入的一端称为队尾(Rear),允许删除的一端称为队头(Front)。
队列的操作是按先进先出(FIFO)的原则进行的。
队列的物理存储可以用顺序存储结构,也可以用链式存储结构。
栈(Stack)也是一种特殊的线性表,是一种后进先出(LIFO)的结构。
栈是限定仅在表尾进行插入和删除运算的线性表,表尾称为栈顶(top),表头称为栈底(bottom)。
栈的物理存储可以用顺序存储结构,也可以用链式存储结构。
List:
java.util.List 线性表 * List是Collection 常用的子接口,是一个可以重复的集合 并且特点是有序。提供了一套通过下标操作元素的方法。 * * 常见实现类: * java.util.ArrayList:内部使用数组实现 * java.util.LinkedList:内部使用链表实现 * * ArrayList 查询性能更好,增删元素慢 * LinkedList 增删元素性能好,尤其首尾增删元素性能最好 但是查询元素效率慢 对性能没有极端苛刻情况下通常使用ArrayList;
void add(int index, Object element) :添加对象element到位置index上
boolean addAll(int index, Collection collection) :在index位置后添加容器collection中所有的元素
Object get(int index) :取出下标为index的位置的元素
int indexOf(Object element) :查找对象element 在List中第一次出现的位置
int lastIndexOf(Object element) :查找对象element 在List中最后出现的位置
Object remove(int index) :删除index位置上的元素
ListIterator listIterator(int startIndex) :返回一个ListIterator 跌代器,开始位置为startIndex
List subList(int fromIndex, int toIndex) :返回一个子列表List ,元素存放为从 fromIndex 到toIndex之前的一个元素
数组转换为List集合:
数组转换为集合
数组的工具类:Arrays提供了一个静态方法asList,可以将 给定的数组转换为一个List集合。
String[] array = {"one","two","three","four"};
List<String> list = Arrays.asList(array);
System.out.println(list); //[one, two, three, four]
/*
* 对该集合的操作就是对原数组的操作
*/
list.set(1, "2");
System.out.println(list); //[one, 2, three, four]
System.out.println(Arrays.toString(array)); // [one, 2, three, four]
/*
* 由于数组是定长的,所以集合增删元素的操作是
* 不支持的,会抛出异常。
*/
// list.add("five");
// System.out.println(list);
// System.out.println(Arrays.toString(array));
/*
* 若想对数组转换的集合元素增删,那只能自行创建
* 一个集合并包含该集合元素。
* 所有集合都提供了一个参数为Collection的构造
* 方法,可有在创建当前集合的同时包含给定集合中
* 的所有元素。
*/
List<String> list1 = new ArrayList<>(list);
System.out.println(list1); //[one, 2, three, four]
list1.add("five");
System.out.println(list1); //[one, 2, three, four, five]
集合转换为数组:
集合转换为数组
Collection定义了一个方法:toArray,可以将当前集合 转换为一个数组
Collection<String> c = new ArrayList<>();
c.add("one");
c.add("two");
c.add("three");
c.add("four");
c.add("five");
System.out.println(c); //[one, two, three, four, five]
// Object[] arr = c.toArray();
String[] arr = c.toArray(new String[c.size()]);
System.out.println(arr.length); //5
System.out.println(Arrays.toString(arr)); //[one, two, three, four, five]
队列:
队列
队列是经典的数据结构之一,队列可以保存一组元素,但是存取元素必须遵循先进先出。
java.util.Queue 接口
Queue继承自Collection,队列定义了存取元素的相关方法。
常用实现类:java.util.LinkedList
Queue<String> queue = new LinkedList<>();
//入队操作,将元素添加到队列末尾
queue.offer("one");
queue.offer("two");
queue.offer("three");
queue.offer("four");
System.out.println(queue); //[one, two, three, four]
/*
* poll 出队操作
* 获取并删除当前队列的队首元素
*/
String str = queue.poll();
System.out.println(str); //one
System.out.println(queue); //[two, three, four]
/*
* peek 引用队首元素
* 获取队首元素,但是不做删除操作
*/
str = queue.peek();
System.out.println(str); //two
System.out.println(queue); //[two, three, four]
/*
* 遍历队列
* 使用迭代器遍历后,元素还是在队列当中的。
*/
for(String s : queue) {
System.out.println(s);
}
System.out.println(queue); //[two, three, four]
双端队列:
java.util.Deque 双端队列
Deque继承自Queue
双端队列是两端都可以进出队的队列。常用实现类:LinkedList
Deque<String> deque = new LinkedList<>();
deque.offer("one");
deque.offer("two");
deque.offer("three");
System.out.println(deque); //[one, two, three]
deque.offerFirst("four");
System.out.println(deque); //[four, one, two, three]
deque.offerLast("five");
System.out.println(deque); //[four, one, two, three, five]
String str = deque.poll();
System.out.println(str); //four
System.out.println(deque); //[one, two, three, five]
str = deque.pollFirst();
System.out.println(str); //one
System.out.println(deque); //[two, three, five]
str = deque.pollLast();
System.out.println(str); //five
System.out.println(deque); //[two, three]
栈:
栈结构
栈也是经典的数据结构之一
栈可以保存一组元素,但是存取必须遵循先进后出原则。
通常使用栈完成"后退"这样的功能
Deque<String> stack = new LinkedList<>();
stack.push("one");
stack.push("two");
stack.push("three");
stack.push("four");
stack.push("five");
System.out.println(stack); //[five, four, three, two, one]
String str = stack.pop();
System.out.println(str); //five
System.out.println(stack); //[four, three, two, one]
//遍历操作
for(String s : stack) {
System.out.println(s);
}
System.out.println(stack); //[four, three, two, one]
//用pop方法遍历栈
while(stack.size()>0) {
String s = stack.pop();
System.out.println(s); // four three two one
}
System.out.println(stack); //[]
集合排序:
Comparator接口
当一个类并未实现Comparable,或者不喜欢缺省的Comaparable行为。可以实现Comparator接口
直接实现Comparator的compare接口完成自定义比较类。
例:Arrays.sort(results, new Comparator<RepDataQueryResultVO>() 数组排序 RepDataQueryExecutor
例:Collections.sort(lst,new Comparator<TaskPrintSchemeVO>()
集合的工具类:java.util.Collections
其提供了一个静态方法:sort,可以对List集合进行自然排序
自然排序(从小到大)
Random random = new Random();
List<Integer> list = new ArrayList<>();
for(int i=0;i<10;i++) {
list.add(random.nextInt(100));
}
System.out.println(list); //[56, 60, 17, 60, 26, 58, 13, 65, 25, 61]
Collections.sort(list);
System.out.println(list); //[13, 17, 25, 26, 56, 58, 60, 60, 61, 65]
//乱序
// Collections.shuffle(list);
// System.out.println(list);
//使用比较器按照数字从大到小排序
Collections.sort(list, new Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
System.out.println(list); //[65, 61, 60, 60, 58, 56, 26, 25, 17, 13]
排序自定义类型元素:
Comparable和Comparator
Comparable 接口以提供自然排序顺序。
对于那些没有自然顺序的类、或者当您想要一个不同于自然顺序的顺序时,您可以实现Comparator 接口来定义您自己的排序函数。可以将Comparator传递给Collections.sort或Arrays.sort。
List<Point> list = new ArrayList<>();
list.add(new Point(5,6));
list.add(new Point(1,9));
list.add(new Point(8,7));
list.add(new Point(4,10));
list.add(new Point(3,2));
list.add(new Point(7,5));
System.out.println(list); //[(5,6), (1,9), (8,7), (4,10), (3,2), (7,5)]
/*
* sort方法要求集合元素必须实现Comparable接口。
* java提供的常用类如:包装类,String等他们都
* 实现了这个接口,定义了元素之间大小规则。
*
* 但是对于我们自定义类型的元素,不建议实现这个
* 接口,因为这样的操作对我们的代码有侵入性,不
* 利于代码维护。
*
*/
// Collections.sort(list);
/*
* 重载的sort方法要求再传入一个参数,是Comparator接口的
* 实现类。
* 该接口是用来单独定义一个比较器,为集合元素制定比较大小
* 的规则。
* 这样一来,该sort方法会将集合元素利用该比较器的比较规则
* 两两比较,并按照从小到大的顺序将集合排序。
*/
Collections.sort(list, new Comparator<Point>() {
/*
* compare方法用来定义参数o1,o2的比较大小规则,
* 返回值是一个整数,该值关注的是取值范围
* 当返回值>0时表示:o1>o2
* 当返回值<0时表示:o1<o2
* 当返回值=0时表示:o1==o2
*/
public int compare(Point o1, Point o2) {
int len1 = o1.getX()*o1.getX()+o1.getY()*o1.getY();
int len2 = o2.getX()*o2.getX()+o2.getY()*o2.getY();
return len1-len2;
}
});
System.out.println(list); //[(3,2), (5,6), (7,5), (1,9), (8,7), (4,10)]
排序字符串:
字符串String已经实现了Comparable接口定义了比较大小的规则
List<String> list = new ArrayList<>();
list.add("安其拉");
list.add("王者荣耀");
list.add("赵云");
System.out.println(list); //[安其拉, 王者荣耀, 赵云]
// Collections.sort(list);
/*
* 对于已经实现了Comparable接口,但是其自身定义的比较
* 规则不满足我们排序需求时,也可以额外提供一个比较器
* 并按照该规则比较后排序。
*/
Collections.sort(list, new Comparator<String>() {
public int compare(String o1, String o2) {
return o1.length()-o2.length();
}
});
System.out.println(list); //[赵云, 安其拉, 王者荣耀]
(与ArrayList相似,区别是Vector是重量级的组件,使用使消耗的资源比较多。)
结论:在考虑并发的情况下用Vector(保证线程的安全)。
在不考虑并发的情况下用ArrayList(不能保证线程的安全)。
扩展Collection接口
无序集合,不允许存放重复的元素;允许使用null元素
对 add()、equals() 和 hashCode() 方法添加了限制
HashSet和TreeSet是Set的实现
HashSet 的后台有一个HashMap;初始化后台容量;只不过生成一个HashSet的话,系统只提供key的访问; 如果有两个Key重复,那么会覆盖之前的;
HashSet:equals返回true,hashCode返回相同的整数;哈希表;存储的数据是无序的。
LinkedHashSet:此实现与HashSet的不同之外在于,后者维护着一个运行于所有条目的双重链接列表。存储的数据是有序的。
HashSet类直接实现了Set接口,其底层其实是包装了一个HashMap去实现的。HashSet采用HashCode算法来存取集合中的元素,因此具有比较好的读取和查找性能。
HashSet的特征:
HashSet常用方法:
实现Set接口的HashSet,依靠HashMap来实现的。 我们应该为要存放到散列表的各个对象定义hashCode()和equals()。
HashSet的equals和HashCode:
前面说过,Set集合是不允许重复元素的,否则将会引发各种奇怪的问题。那么HashSet如何判断元素重复呢?
HashSet需要同时通过equals和HashCode来判断两个元素是否相等,具体规则是,如果两个元素通过equals为true,并且两个元素的hashCode相等,则这两个元素相等(即重复)。
所以如果要重写保存在HashSet中的对象的equals方法,也要重写hashCode方法,重写前后hashCode返回的结果相等(即保证保存在同一个位置)。所有参与计算 hashCode() 返回值的关键属性,都应该用于作为 equals() 比较的标准。
试想如果重写了equals方法但不重写hashCode方法,即相同equals结果的两个对象将会被HashSet当作两个元素保存起来,这与我们设计HashSet的初衷不符(元素不重复)。
另外如果两个元素哈市Code相等但equals结果不为true,HashSet会将这两个元素保存在同一个位置,并将超过一个的元素以链表方式保存,这将影响HashSet的效率。
如果重写了equals方法但没有重写hashCode方法,则HashSet可能无法正常工作;
“键”就是我们要存入的对象,“值”则是一个常量。这样可以确保,我们所需要的存储的信息是“键”。而“键”在Map中是不能重复的,这就保证了我们存入Set中的所有的元素都不重复。
HashSet如何过滤重复元素
调用元素HashCode获得哈希码--》判断哈希码是否相等,不相等则录入 ---》相等则判断equals()后是否相等,不相等在进行 hashcode录入,相等不录入
LinkedHashSet是HashSet的一个子类,LinkedHashSet也根据HashCode的值来决定元素的存储位置,但同时它还用一个链表来维护元素的插入顺序,插入的时候即要计算hashCode又要维护链表,而遍历的时候只需要按链表来访问元素。
LinkedHashSet本质上也是从LinkedHashMap而来,LinkedHashSet的所有方法都继承自HashSet, 而它能维持元素的插入顺序的性质则继承自LinkedHashMap.
下面是一个LinkedHashSet维持元素插入顺序的例子:
Set set = new LinkedHashSet();
set.add("abc");
set.add("efg");
set.add("hjk");
System.out.println(set); //[abc, efg, hjk]
set.remove(new String("abc"));
set.add("abc");
System.out.println(set); //[efg, hjk, abc]
几种Set的比较:
HashSet外部无序地遍历成员。
成员可为任意Object子类的对象,但如果覆盖了equals方法,同时注意修改hashCode方法。
TreeSet外部有序地遍历成员;
附加实现了SortedSet, 支持子集等要求顺序的操作
成员要求实现Comparable接口,或者使用Comparator构造TreeSet。成员一般为同一类型。
LinkedHashSet外部按成员的插入顺序遍历成员
成员与HashSet成员类似
HashSet是基于Hash算法实现的,其性能通常都优于TreeSet。我们通常都应该使用HashSet,在我们需要排序的功能时,我们才使用TreeSet。
HashSet的元素存放顺序和我们添加进去时候的顺序没有任何关系,而LinkedHashSet 则保持元素的添加顺序。TreeSet则是对我们的Set中的元素进行排序存放。
一般来说,当您要从集合中以有序的方式抽取元素时,TreeSet实现就会有用处。为了能顺利进行,添加到 TreeSet 的元素必须是可排序的。 而您同样需要对添加到TreeSet中的类对象实现 Comparable 接口的支持。一般说来,先把元素添加到 HashSet,再把集合转换为 TreeSet 来进行有序遍历会更快。
各种Set集合性能分析
集合框架的第二类接口树。
它提供了一组键值的映射。其中存储的每个对象都有一个相应的关键字(key),关键字决定了对象在Map中的存储位置。
关键字应该是唯一的,每个key 只能映射一个value。
实现类:
HashMap、TreeMap、LinkedHashMap、Hashtable等
Hash哈希算法的意义在于提供了一种快速存取数据的方法,它用一种算法建立键值与真实值之间的对应关系。散列表又称为哈希表。散列表算法的基本思想是:以结点的关键字为自变量,通过一定的函数关系(散列函数)计算出对应的函数值,以这个值作为该结点存储在散列表中地址。
当散列表中的元素存放太满,就必须进行再散列,将产生一个新的散列表,所有元素存放到新的散列表中,原先的散列表将被删除。在Java语言中,通过负载因子(load factor)来决定何时对散列表进行再散列。例如:如果负载因子0.75,当散列表中已经有75%位置已经放满,那么将进行再散列。
负载因子越高(越接近1.0),内存的使用效率越高,元素的寻找时间越长。负载因子越低(越接近0.0),元素的寻找时间越短,内存浪费越多。
当一个类有自己特有的“逻辑相等”概念(不同于对象身份的概念);
Object类仅仅提供了一个对引用的比较,如果两个引用不是同一个那就返回false,这是无法满足大多数对象比较的需要的,所以要覆盖;
使用==操作符检查实参是否为指向对象的引用”
使用instanceof操作符检查实参是否为正确的类型
把实参转换到正确的类型;
对于该类中每一个“关键”域,检查实参中的域与当前对象中对应的域值是否匹配。对于既不是float也不是double类型的基本类型的域,可以使用==操作符进行比较;对于对象引用类型的域,可以递归地调用所引用的对象的equals方法,对于float和double类型的域,先转换成int或long类型的值,然后使用==操作符比较;
当你编写完成了equals方法之后,应该问自己三个问题:它是否是对称的、传 递的、一致的? 如果答案是否定的,那么请找到 这些特性未能满足的原因,再修改equals方法的代码
尤其强调当一个对象被当作键值(或索引)来使用的时候要重写这两个方法;
覆写equals后,两个不同实例可能在逻辑上相等,但是根据Object.hashCode方法却产生不同的散列码,违反“相等的对象必须具有相等的散列码”。
导致,当你用其中的一个作为键保存到hashMap、hasoTable或hashSet中,再以“相等的”找另 一个作为键值去查找他们的时候,则根本找不到
不同类型的hashCode取值
Map集合比较:
注意:TreeMap中是根据键(Key)进行排序的。而如果我们要使用TreeMap来进行正常的排序的话,Key 中存放的对象必须实现Comparable 接口。
Map常用方法:
java.util.Map 查找表
Map是java中非常经典的数据结构之一
Map的结构看起来像是一个多行两列的表格,其中左列称为:Key
右列称为:Value
Map总是以Key-Value对的形式保存数据的。并且Map提供了根据Key获取其对应的Value的查找方法。
Map有一个要求:Key是不允许重复的(Key的equals方法决定)
常用实现类:java.util.HashMap
HashMap称为散列表或哈希表,使用散列算法实现的Map,是当今世界上查询速度最快的数据结构。其查询速度不受数据量影响,现如今所有网站的缓存都是用HashMap来实现。
Map<String,Integer> map = new HashMap<>();
/*
* V put(K k,V v)
* 将给定的key,value对保存到Map中
* 若给定的Key在当前Map中已经存在,则是替换value
* 操作,那么返回值就是原Key对应的Value
* 否则返回值为null
*/
Integer num = map.put("语文", 99);
System.out.println(num); //null
map.put("数学", 98);
map.put("英语", 97);
map.put("物理", 96);
map.put("化学", 99);
System.out.println(map); //{物理=96, 数学=98, 化学=99, 语文=99, 英语=97}
num = map.put("语文", 88);
System.out.println(map); //{物理=96, 数学=98, 化学=99, 语文=88, 英语=97}
System.out.println(num); //99
/*
* V get(Object key)
* 根据给定的key获取对应的value,若给定的key在
* Map中不存在,则返回值为null。
*/
num = map.get("数学");
System.out.println("数学:"+num); //数学:98
num = map.get("体育");
System.out.println("体育:"+num); //体育:null
int size = map.size();
System.out.println("size:"+size); //size:5
/*
* V remove(Object key)
* 删除给定的key所对应的键值对
* 返回值为该key对应的value。
*/
num = map.remove("英语");
System.out.println(map); //{物理=96, 数学=98, 化学=99, 语文=88}
/*
* boolean containsKey(Object key)
* boolean containsValue(Object value)
* 判断当前Map是否包含给定的key或value
* 是否包含还是依据元素自身equals比较的结果
*/
boolean ck = map.containsKey("语文");
System.out.println("包含key:"+ck); //包含key:true
boolean cv = map.containsValue(97);
System.out.println("包含value:"+cv); //包含value:false
Map的遍历:
Map的遍历
* 遍历Map有三种方式:
* 遍历所有的key
* 遍历所有的key-value对
* 遍历所有的value(相对不常用)
Map<String,Integer> map = new HashMap<>();
map.put("语文", 99);
map.put("数学", 98);
map.put("英语", 97);
map.put("物理", 96);
map.put("化学", 99);
System.out.println(map); //{物理=96, 数学=98, 化学=99, 语文=99, 英语=97}
/*
* Set keySet()
* 将当前Map中所有的key以一个Set集合形式返回
*/
Set<String> keySet = map.keySet();
for(String key : keySet) {
System.out.println("key:"+key); //key:物理 key:数学 ......
}
/*
* Set<Entry> entrySet()
* 将当前Map中每一组键值对一个Entry实例形式存放
* 于Set集合后返回
*
* java.util.Map.Entry
* Entry的每一个实例用于表示Map中的一组键值对
*
*/
Set<Entry<String,Integer>> entrySet = map.entrySet();
for(Entry<String,Integer> entry:entrySet) {
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key+":"+value); //物理:96 数学:98....
}
/*
* Collection values()
* 将当前Map中所有的Value以一个Collection集合的
* 形式返回。之所以没有用Set集合返回,是因为Map
* 中的value是可以重复的。
*/
Collection<Integer> values = map.values();
for(Integer value : values) {
System.out.println("value:"+value); //value:96 value:98.....
}
总结:
HashMap和Hashtable都是java的集合类,都可以用来存放java对象,这是他们的相同点
以下是他们的区别:
ArrayList和Vector的区别:
ArrayList与Vector都是java的集合类,都是用来存放java对象,这是他们的相同点,
区别:
总结:
arraylist和linkedlist联系与区别:
HashMap与TreeMap联系与区别:
两个map中的元素一样,但顺序不一样,导致hashCode()不一样。
同样做测试:
在HashMap中,同样的值的map,顺序不同,equals时,false;
而在treeMap中,同样的值的map,顺序不同,equals时,true,说明,treeMap在equals()时是整理了顺序了的。
标签:排列 动态 直接 包装 lifo sync 顺序存储 == 内容
原文地址:https://www.cnblogs.com/jyy599/p/12032065.html