一、为什么要使用集合
当定义一个数组来存数据的时候长度可能不够用,此时集合类是最好的考虑
二、集合间的区别
1. ArrayList与LinkedList的区别
1.1 ArrayList的内部实现是数组,每当删除或增加一个元素的时候整个数组就会移动;优势是在进行查询的时候比较快速,因为只要找到ArrayList元素的下标即可进行操作,所以在对数组进行大量查询操作的时候,用ArrayList
ArrayList<Integer> a = new ArrayList<Integer>();// 动态数组
a.add(1);
a.add(2);
a.add(3);
a.add(4);
List<Integer> b = a.subList(2, 4);
for (Integer temp : b) {
out.println(temp);
}
out.println(a.indexOf(2)); // 通过indexof充分体现了这个内部的实现原理就是数组
out.println(a.indexOf(21));
1.2 LinkedList的内部实现是链表,每当删除或增加一个元素的时候只需对链表的节点进行操作就行,不用移动整个数组;优势是在进行修改和删除的时候比较快速,因为只要找到对应的链表节点即可进行删除,在进行大量的修改和删除操作的时候使用LinkedList
LinkedList<Integer> a = new LinkedList<Integer>();// 链表
a.add(1);
a.add(2);
a.add(3);
a.add(4);
for (Integer temp : a) {
out.println(temp);
}
2. ArrayList与Vector的区别
2.1 ArrayList是非线程安全的,采用异步处理模式,性能更高,适合单线程场景
2.2 Vector是线程安全的,采用同步处理模式,性能较低
2.3 两个集合类的方法在使用上完全一样
3. HashSet、linkedHashSet、TreeSet的区别
3.1 HashSet的实现原理是哈希表,内部元素是无序不可重复的,插入的元素在输出的时候也是无序的,如果要保证插入顺序即为输出顺序的话使用LinkedHashSet
class aaa {
aaa(int i) {
this.i = i;
}
int i = 1;
}
public class Test {
public static void main(String[] args) {
// hashset不能保证插入数据的顺序,特别是保证该代码一直不变,
实现原理是哈希表
// 如果要保证插入顺序即为输出顺序的话使用LinkedHashSet
HashSet<aaa> h1 = new HashSet<aaa>();
h1.add(new aaa(2));// 分配堆内存以后把地址给h1
h1.add(new aaa(5));
h1.add(new aaa(2));// 虽然set不能有重复的但这两个值其实是不一样的因为new的地址不一样
h1.add(new aaa(4));
h1.add(new aaa(6));
h1.add(new aaa(0));
for (aaa j : h1) {
out.println(j.i);// 遍历输出h1地址指向的值
}
h1.add(null);// 此类允许使用 null 元素,但不能空输出
}
}
输出结果:2,0,6,2,5,4
3.2、LinkedHashSet的实现原理是哈希表和链表,可以对插入的元素进行原样输出
package com.study.test;
import static java.lang.System.out;
import java.util.LinkedHashSet;
class aaa {
aaa(int i) {
this.i = i;
}
int i = 1;
}
public class Test {
public static void main(String[] args) {
LinkedHashSet<aaa> h1 = new LinkedHashSet<aaa>();
// 具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现
h1.add(new aaa(2));
h1.add(new aaa(2));// 这里两个 new aaa()其实是不一样的
h1.add(new aaa(1));
h1.add(new aaa(4));
h1.add(new aaa(3));
for (aaa temp : h1) {
out.println(temp.i);
}
h1.add(null);// 此类允许使用 null 元素
}
}
输出结果:2,2,1,4,3
3.3、TreeSet可以对插入的元素进行排序后再输出,会把一样的值去掉一个
TreeSet<Integer> h1 = new TreeSet<Integer>();
// 可以排序的set
h1.add(2);
h1.add(3);
h1.add(8);
h1.add(4);
h1.add(4);
for (int temp : h1) {
out.println(temp);
}
输出结果:2,3,4,8
4. HashMap和Hashtable的区别
4.1、HashMap是非线程安全的,采用异步处理模式,性能更高
4.2、Hashtable是线程安全的,采用同步处理模式,性能较低
4.3、两个集合类的方法再使用上完全一样
5. HashMap和IdentityHashMap的区别
5.1、HashMap的内部是用equals来比较的,比较的是内容,当键值内容相等时,不允许重复的键值
5.2、IdentityHashMap内部是用==来比较的,比较的是地址,当地址不相同但内容相同时是允许重复的
package com.study.test;
import static java.lang.System.out;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
class aa implements Comparable<aa> {
int i = 1;
aa(int i) {
this.i = i;
}
@Override
public int compareTo(aa o) { // 这函数就是排序的依据
// TODO Auto-generated method stub
return this.i - o.i;
}
}
public class Test {
public static void main(String[] args) {
HashMap<Integer, String> k = new HashMap<Integer, String>();
// TODO Auto-generated method stub
HashMap<String, String> k1 = new HashMap<String, String>();// 用equals比较 比较的是内容
String s1 = new String("1");
String s2 = new String("2");
String s3 = new String("2");
String s4 = new String("3");
k1.put(s1, "tom");
k1.put(s2, "jack");
k1.put(s3, "jack1");
k1.put(s4, "mary");
for (Entry<String, String> temp : k1.entrySet()) {
out.println(temp.getKey() + "," + temp.getValue());
}
out.println(k1.size());
// 用==比较,比较的是地址
// 此类不是 通用 Map 实现!此类实现 Map 接口时,它有意违反 Map 的常规协定,
// 该协定在比较对象时强制使用 equals 方法。此类设计仅用于其中需要引用相等性语义的罕见情况。
out.println("---------------identityHashMap-----------------");
IdentityHashMap<String, String> k2 = new IdentityHashMap<String, String>();// 用==比较,比较的是地址
k2.put(s1, "tom");
k2.put(s2, "jack");
k2.put(s3, "jack1");
k2.put(s4, "mary");
for (Entry<String, String> temp : k2.entrySet()) {
out.println(temp.getKey() + "," + temp.getValue());
}
out.println(k1.size());
}
}
输出结果:
1,tom
2,jack1
3,mary
3
---------------identityHashMap-----------------
1,tom
2,jack1
3,mary
2,jack
3
6. TreeSet和TreeMap的区别
6.1、TreeSet与TreeMap实现原理都是红黑树,都能够对内部元素进行排序后输出
6.2、都要实现Comparable<T>泛型接口,否则不能比较
package com.study.test;
import static java.lang.System.out;
import java.util.Map.Entry;
import java.util.TreeMap;
class aaa implements Comparable<aaa> {
aaa(int i) {
this.i = i;
}
int i = 1;
@Override
public int compareTo(aaa o) {
// TODO Auto-generated method stub
return this.i - o.i;
}
}
public class Test {
public static void main(String[] args) {
TreeMap<aaa, String> h1 = new TreeMap<aaa, String>();
// 可以排序的set
h1.put(new aaa(2), "jack");
h1.put(new aaa(1), "tom");
h1.put(new aaa(3), "mary");
for (Entry<aaa, String> temp : h1.entrySet()) {
out.println(temp.getKey().i + "," + temp.getValue());
}
// 因为Integer是实现了Comparable接口的,所以做为key的比较
TreeMap<Integer, String> h2 = new TreeMap<Integer, String>();
// 可以排序的set
h2.put(2, "jack");
h2.put(1, "tom");
h2.put(3, "mary");
for (Entry<Integer, String> temp : h2.entrySet()) {
out.println(temp.getKey() + "," + temp.getValue());
}
}
}
三、集合的方法的使用
1. HashMap和Hashtable各种方法的使用(HashMap与Hashtable的使用完全一样)
package com.study.test;
import static java.lang.System.out;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
class aa implements Comparable<aa> {
int i = 1;
aa(int i) {
this.i = i;
}
@Override
public int compareTo(aa o) { // 这函数就是排序的依据
// TODO Auto-generated method stub
return this.i - o.i;
}
}
public class Test {
public static void main(String[] args) {
HashMap<Integer, String> k = new HashMap<Integer, String>();
// 增加
k.put(1, "jack");
k.put(2, "rose");
k.put(3, "alan");
k.put(4, "jim");
// out.println(k.size());
// 删除
k.remove(1);
// out.println(k.size());
// 改 先删除再修改
// 查
// out.println(k.get(2));
// bollean型
// out.println(k.containsKey(2));//s输出为true
// out.println(k.containsValue("rose"));
// HashMap<Integer,String> k1=new HashMap<Integer,String>();
// //增加元素
// k1.put(11, "lgs");
// k1.put(22, "yc");
// 把一个HashMap添加到另一个HashMap里面去
// k.putAll(k1);
// out.println(k.size());
// k.clear();清除k中的所有元素
// out.println(k.isEmpty());
// Set<Integer> s1=k.keySet();
// for(Integer s:s1){
// out.println(s);
// }
// Collection<String> c=k.values();
// for(String s:c){
// out.println(s);
// }
// //输出HashMap的内容
// //使用entrySet()方法将键值封装成set类型的
Set<Entry<Integer, String>> k1 = k.entrySet();
// //遍历输出set的内容
for (Entry<Integer, String> k2 : k1) {
out.println(k2.getKey() + "," + k2.getValue());
}
// 拆解set里面的内容
// 迭代输出set里面的内容
out.println("-------迭代输出set里面的内容-------");
Iterator<Entry<Integer, String>> i1 = k1.iterator();
while (i1.hasNext()) {
Entry<Integer, String> e = i1.next();
out.println(e.getKey() + "," + e.getValue());
}
}
}
2. PriorityQueue优先队列各种方法的使用
package com.study.test;
import static java.lang.System.out;
import java.util.PriorityQueue;
public class Test {
public static void main(String[] args) {
// 队列:先进先出
// 优先队列
PriorityQueue<Integer> p = new PriorityQueue<Integer>();
p.add(1);// 把元素添加到队列的尾部,如果空间不够自动开辟空间
p.add(2);
p.offer(3);// 把元素添加到队列的尾部,如果空间不够不会自动开辟空间,适用于空间被指定的队列集合
// out.println(p.size());
// p.remove();//获取队列头部的元素并删除
// for(Integer p1:p){
// out.println(p1);
// }
out.println(p.peek());// peek()方法看一下头部元素而已 不删除 队列为空时返回null
out.println(p.size());
out.println(p.element());// element()方法获取队列的头部元素 不删除
out.println(p.size());
out.println(p.poll());// poll()方法获取队列的头部元素 并删除 队列为空时返回null
out.println(p.size());
for (Integer p1 : p) {
out.println(p1);
}
}
}
3. 双向链表LinkedList中各种方法的使用
package com.study.test;
import static java.lang.System.out;
import java.util.LinkedList;
public class Test {
public static void main(String[] args) {
// 双向队列
LinkedList<Integer> l = new LinkedList<Integer>();
// l.add(9);//将指定元素插入双向队列的尾部
// l.push(18);//push()方法将一个元素放入双向队列的头部
l.addFirst(1);// 将指定元素插入双向队列的开头 与offerFist()方法类似
l.addFirst(2);
l.addFirst(3);
// l.add(9);//将指定元素插入双向队列的尾部
// l.add(19);//将指定元素插入双向队列的尾部
l.addLast(4);// 将指定元素插入双向队列的结尾 offerLast()方法类似
l.addLast(1);
// for(Integer k:l){
// out.println(k);
//
// }
// out.println(l.getFirst());//获取双向队列的第一个元素
// out.println(l.getLast());//获取双向队列的最后一个元素
// out.println(l.removeFirstOccurrence(1)); //删除第一个重复的
// for(Integer k:l){
// out.println(k);
//
// }
// out.println(l.removeLastOccurrence(1)); //删除最后一个重复的
for (Integer k : l) {
out.println(k);
}
//
// out.println(pq.peekFirst());
// out.println(pq.peekLast());
// out.println(pq.pollFirst());
// out.println(pq.pollLast());
// out.println("----------------");
// for(Integer temp:pq)
// out.println(temp);
// out.println(pq.pop());
// out.println(pq.removeFirst());
// out.println("----------------");
// for(Integer temp:pq)
// out.println(temp);
}
}
4. Properties的使用(自己创建读取Properties文件的过程)
package com.study.test;
import static java.lang.System.out;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
public class Test {
public static void main(String[] args) throws FileNotFoundException, IOException {
// TODO Auto-generated method stub
// 创建配置文件过程
Properties pOut = new Properties();
// 设置配置文件的属性
pOut.setProperty("username", "pw1");
pOut.setProperty("username1", "pw2");
// 把文件存到硬盘上并命名
pOut.store(new FileOutputStream("test.properties"), "ini file");
// 从硬盘读取配置文件的过程
Properties pIn = new Properties();
pIn.load(new FileInputStream("test.properties"));
Set<Entry<Object, Object>> s1 = pIn.entrySet();
for (Entry<Object, Object> s : s1) {
out.println(s.getKey() + "," + s.getValue());
}
}
}
输出结果:
username1,pw2
username,pw1