笔记:Java SE之集合
一. Java 集合可分为 Collection 和 Map 两种体系
1. Collection 接口:
①. Set:元素无序、不可重复的集合。类似于高中的" 集合 "
②. List:元素有序,可重复的集合。" 动态 " 数组
2. Map 接口:具有映射关系 " key-value " 的集合。类似于高中的 " 函数 "
3. 总结:
①. 存储对象可以考虑:①. 数组 ②. 集合
②. 数组存储对象的弊端:①. 一旦创建,长度不可变 ②. 真是的数组存放的对象的个数是不可知的
二. collection 接口
public void testCollection1() {
Collection coll=new ArrayList();
//1. coll.size(); 返回集合中元素的个数
System.out.println(coll.size());
//2. coll.add(Object obj); 向集合中添加一个元素
coll.add(123);
coll.add("AA");
coll.add(new Date());
coll.add("BB");
System.out.println(coll.size());
//3. coll.addAll(Collection coll); 将形参coll中包含的所有元素添加到当前集合中
Collection coll1=Arrays.asList(1,2,3);
coll.addAll(coll1);
System.out.println(coll.size());
//查看集合元素
System.out.println(coll);
//4. coll.isEmpty(); 判断集合是否为空
System.out.println(coll.isEmpty());
//5. clear(); 清空集合元素
coll.clear();
System.out.println(coll.isEmpty());
System.out.println();
}
public void testCollection2() {
Collection coll=new ArrayList();
Person p=new Person("小明", 13);
coll.add(123);
coll.add("AA");
coll.add(new Date());
coll.add("BB");
coll.add(p);
System.out.println(coll);
//6. coll.contains(Object obj) 判断集合中是否包含指定的 obj 元素。
//若包含返回 true,否则返回 false
//判断的一句:根据元素所在的类的 equals() 方法进行判断
//明确:如果存入集合中的元素是自定义类的对象。要求:自定义类要重写 equals() 方法
System.out.println(coll.contains(123));
System.out.println(coll.contains(p));
//7. coll.containsAll(); 判断当前集合中是否包含 coll 中的所有的元素
Collection coll1=new ArrayList();
coll1.add(123);
coll1.add("AA");
System.out.println("#"+ coll.containsAll(coll1));
//8. coll.retainAll(Collection coll); 求当前集合与 coll 的共有元素,返回给当前集合
coll.retainAll(coll1);
System.out.println(coll);
//9. coll.remove(Object obj) 删除集合中的 obj 元素。若删除成功,返回 true,否则返回 false
System.out.println(coll.remove("BB"));
System.out.println();
}
public void testCollection3() {
Collection coll=new ArrayList();
Person p=new Person("小明", 13);
coll.add(123);
coll.add("AA");
coll.add(new Date());
coll.add("BB");
coll.add(p);
Collection coll1=new ArrayList();
coll1.add(123);
coll1.add("AA");
//10. coll.removeAll(Collection coll); 从当前集合中删除包含在 coll 中的集合
coll.removeAll(coll1);
System.out.println(coll);
//11. coll.equals(Object obj); 判断集合中的所有元素是否完全相同
Collection coll2=new ArrayList();
coll2.add(new Date());
coll2.add("BB");
coll2.add(p);
System.out.println(coll2);
System.out.println(coll.equals(coll2));
//12. coll.hashCode();
System.out.println(coll.hashCode());
//13. coll.toArray(); 将集合转换为数组
Object[] objects=coll.toArray();
for (int i = 0; i < objects.length; i++) {
System.out.println(objects[i]);
}
//13. coll.iterator(); 返回一个 Iterator 接口实现类的对象,遍历集合
Iterator iterator = coll.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
1. List 接口:
①. ArrayList
public void testList(){
//坑:要引用 java.util.List,不能引用 java.awt.List,不然报错
List list=new ArrayList();
list.add(123);
list.add(456);
list.add(new String("AA"));
list.add(new String("GG"));
System.out.println(list);
//1. list.add(int index,Object ele);
//在指定的索引位置 index 添加元素 ele
// list.addAll(int index,Collection eles);
//与 collection的 addAll 相同
list.add(0,555);
System.out.println(list);
//2. list.get(int index); 获取指定索引位置的元素
System.out.println(list.get(1));
//3. list.remove(int index); 删除指定索引位置的元素
list.remove(3);
System.out.println(list);
//3. list.set(int index,Object ele); 设置指定索引位置的元素为ele
list.set(3,"666");
System.out.println(list);
}
public void testList2(){
List list=new ArrayList();
list.add(123);
list.add(456);
list.add(new String("AA"));
list.add(new String("GG"));
System.out.println(list);
list.add(456);
// list.indexOf(Object ele);
//返回 obj 在集合中首次出现的位置,若没有,返回 -1
System.out.println(list.indexOf(456));
// list.lastIndexOf(Object ele);
//返回 obj 在集合中最后出现的位置,若没有,返回 -1
System.out.println(list.lastIndexOf(456));
System.out.println(list.indexOf(123) == list.lastIndexOf(123));
System.out.println(list.indexOf(444));
//list.subList(fromIndex, toIndex);
//返回从 fromIndex 到 toIndex 结束的左闭右开的一个子 list
System.out.println(list.subList(0, 2));
}
②. LinkedList:对于频繁的插入和删除操作
③. Vector:古老的实现类、线程安全(即使 ArrayList 线程不安全,也不会用 Vector ,太老了,插入删除比较慢)
2. Set 接口:
①. HashSet
public void testSet(){
Set set=new HashSet();
set.add(123);
set.add(456);
set.add(new String("AA"));
set.add(new String("BB"));
set.add(null);
Person p1 = new Person("GG", 23);
Person p2 = new Person("GG", 23);
System.out.println(p1.equals(p2));
set.add(p1);
set.add(p2);
System.out.println(set.size());
/*
* 1. 无序性 != 随机性 无序性是元素在底层存储的位置是无序的
* 2. 不可重复行,当 Set 中添加相同 的元素时,不能添加进去
*
* 说明:要求添加进 Set 中的元素所在的类,
* 一定要重写 equals() 和 hashCode() 方法
* 进而保证 Set 中元素的不可重复性
*
* Set 存储方式使用的是哈希算法
*
*/
System.out.println(set);
}
②. LinkedHashSet
public void testLinkedHashSet(){
/*
* 1. LinkedHashSet 根据元素的 hashCode 值来决定元素的存储位置,
* 但它同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的
* 2.性能上略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能
*
* */
Set set=new LinkedHashSet();
set.add(123);
set.add(456);
set.add(new String("AA"));
set.add(new String("BB"));
set.add(null);
Iterator iterator =set.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
③. TreeSet
⑴. 自然排序
/*
* TreeSet: 1.向TreeSet中添加的元素必须是同一个类的。
* 2.可以按照添加进集合中的元素的指定的顺序遍历。像String,包装类等默认按照从小到大的顺序遍历。
* 3.当向TreeSet中添加自定义类的对象时,有两种排序方法:①自然排序②定制排序
* 4.自然排序:要求自定义类实现java.lang.Comparable接口并重写其compareTo(Object obj)的抽象方法
* 在此方法中,指明按照自定义类的哪个属性进行排序。
*
* 5.向TreeSet中添加元素时,首先按照compareTo()进行比较,一旦返回0,虽然仅是两个对象的此
* 属性值相同,但是程序会认为这两个对象是相同的,进而后一个对象就不能添加进来。
*
* >compareTo()与hashCode()以及equals()三者保持一致!
*/
@Test
public void testTreeSet1() {
Set set = new TreeSet();
// set.add(new String("AA"));
// set.add(new String("AA"));
// set.add("JJ");
// set.add("GG");
// set.add("MM");
// 当Person类没有实现Comparable接口时,当向TreeSet中添加Person对象时,报ClassCastException
set.add(new Person("CC", 23));
set.add(new Person("MM", 21));
set.add(new Person("GG", 25));
set.add(new Person("JJ", 24));
set.add(new Person("KK", 20));
set.add(new Person("DD", 20));
// set.add("AA");
for (Object str : set) {
System.out.println(str);
}
}
// Person 中的 重写 compareTo 方法
// 当向TreeSet中添加Person类的对象时,依据此方法,确定按照哪个属性排列。
@Override
public int compareTo(Object o) {
if(o instanceof Person){
Person p = (Person)o;
//return this.name.compareTo(p.name);
//return -this.age.compareTo(p.age);
int i = this.age.compareTo(p.age);
if(i == 0){
return this.name.compareTo(p.name);
}else{
return i;
}
}
return 0;
}
⑵. 定制排序
/*
* TreeSet的定制排序: 见下面的步骤 compare()与hashCode()以及equals()三者保持一致!
*/
@Test
public void testTreeSet2() {
// 1.创建一个实现了Comparator接口的类对象
Comparator com = new Comparator() {
// 向TreeSet中添加Customer类的对象,在此compare()方法中,指明是按照Customer
// 的哪个属性排序的。
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Customer && o2 instanceof Customer) {
Customer c1 = (Customer) o1;
Customer c2 = (Customer) o2;
int i = c1.getId().compareTo(c2.getId());
if (i == 0) {
return c1.getName().compareTo(c2.getName());
}
return i;
}
return 0;
}
};
// 2.将此对象作为形参传递给TreeSet的构造器中
TreeSet set = new TreeSet(com);
// 3.向TreeSet中添加Comparator接口中的compare方法中涉及的类的对象。
set.add(new Customer("AA", 1003));
set.add(new Customer("BB", 1002));
set.add(new Customer("GG", 1004));
set.add(new Customer("CC", 1001));
set.add(new Customer("DD", 1001));
for (Object str : set) {
System.out.println(str);
}
}
三. Iterator 遍历
public void testIterator(){
Collection coll=new ArrayList();
Person p=new Person("小明", 13);
coll.add(123);
coll.add("AA");
coll.add(new Date());
coll.add("BB");
coll.add(p);
//使用迭代器 Iterator 实现集合的遍历
Iterator iterator = coll.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
//使用增强 for 实现集合的遍历
for(Object i : coll){//只是将coll遍历的值复制给 i,i是形参
System.out.println(i);
}
}
四. Map 接口
1. 知识点:
①. Map 与 Collection 并列存在。用于保存具有映射关系的数据:Key - Value
②. Map 中的 key 和 value 都可以是任何引用类型的数据
③. Map 对象所对应的类,需要重写 hashCode() 和 equals() 方法
④. 常用 String 类作为 Map 的" 键 "
⑤. key 和 value 之间存在单向一对一关系,即通过指定的 key 总能找到唯一的、确定的 value
⑥. |-----HashMap:Map的主要实现类
* |-----LinkedHashMap:使用链表维护添加进Map中的顺序。故遍历Map时,是按添加的顺序遍历的。
* |-----TreeMap:按照添加进Map中的元素的key的指定属性进行排序。要求:key必须是同一个类的对象!
* 针对key:自然排序 vs 定制排序
* |-----Hashtable:古老的实现类,线程安全,不建议使用。
* |----Properties:常用来处理属性文件。键和值都为String类型的
2. HashMap
①. 常用操作
/*
* Object put(Object key,Object value):向Map中添加一个元素
* Object remove(Object key):按照指定的key删除此key-value
* void putAll(Map t)
* void clear():清空 Object
* get(Object key):获取指定key的value值。若无此key,则返回null
* boolean containsKey(Object key)
* boolean containsValue(Object value)
* int size():返回集合的长度 boolean
* isEmpty() boolean equals(Object obj)
*
* HashMap: 1.key是用Set来存放的,不可重复。value是用Collection来存放的,可重复
* 一个key-value对,是一个Entry。所有的Entry是用Set存放的,也是不可重复的。
* 2.向HashMap中添加元素时,会调用key所在类的equals()方法,判断两个key是否相同。若相同 则只能添加进后添加的那个元素。
*/
@Test
public void test1() {
Map map = new HashMap();
map.put("AA", 213);
map.put("BB", 456);
map.put("BB", 45);
map.put(123, "CC");
map.put(null, null);
map.put(new Person("DD", 23), 89);
map.put(new Person("DD", 23), 87);
System.out.println(map.size());
System.out.println(map);
map.remove("BB");
System.out.println(map);
Object value = map.get(1234);
System.out.println(value);
}
②. Map 的遍历
/*
* 如何遍历Map Set keySet() Collection values() Set entrySet()
*/
@Test
public void test2() {
Map map = new HashMap();
map.put("AA", 213);
map.put("BB", 45);
map.put(123, "CC");
map.put(null, null);
map.put(new Person("DD", 23), 89);
// 1.遍历key集。
Set set = map.keySet();
for (Object obj : set) {
System.out.println(obj);
}
// 2.遍历value集
Collection values = map.values();
Iterator i = values.iterator();
while (i.hasNext()) {
System.out.println(i.next());
}
// 3.如何遍历key-value对。
// 方式一:
Set set1 = map.keySet();
for (Object obj : set1) {
System.out.println(obj + "----->" + map.get(obj));
}
// 方式二:
Set set2 = map.entrySet();
for (Object obj : set2) {
Map.Entry entry = (Map.Entry) obj;
// System.out.println(entry.getKey() + "---->" + entry.getValue());
System.out.println(entry);
}
}
③. LinkedHashMap
/*
* 原理和 LinkedHashSet 相同
*
*/
@Test
public void test3() {
Map map = new LinkedHashMap();
map.put("AA", 213);
map.put("BB", 45);
map.put(123, "CC");
map.put(null, null);
map.put(new Person("DD", 23), 89);
Set set1 = map.keySet();
for (Object obj : set1) {
System.out.println(obj + "----->" + map.get(obj));
}
}
④. TreeMap
⑴. 自然排序
//自然排序
@Test
public void test4() {
Map map = new TreeMap();
map.put(new Person("AA", 23), 89);
map.put(new Person("MM", 22), 79);
map.put(new Person("GG", 23), 99);
map.put(new Person("JJ", 13), 69);
Set set1 = map.keySet();
for (Object obj : set1) {
System.out.println(obj + "----->" + map.get(obj));
}
}
⑵. 定制排序
//定制排序
@Test
public void test5() {
Comparator com = new Comparator() {
public int compare(Object o1, Object o2) {
if (o1 instanceof Customer && o2 instanceof Customer) {
Customer c1 = (Customer) o1;
Customer c2 = (Customer) o2;
int i = c1.getId().compareTo(c2.getId());
if (i == 0) {
return c1.getName().compareTo(c2.getName());
}
return i;
}
return 0;
}
};
TreeMap map = new TreeMap(com);
map.put(new Customer("AA", 1001), 87);
map.put(new Customer("CC", 1001), 67);
map.put(new Customer("MM", 1004), 77);
map.put(new Customer("GG", 1002), 97);
Set set1 = map.keySet();
for (Object obj : set1) {
System.out.println(obj + "----->" + map.get(obj));
}
}
⑤. Hashtable
⑴. Hashtable 是个古老的 Map 实现类,线程安全
⑵. 与 HashMap 不同,Hashtable 不允许使用 null 作为 key 和 value
⑶. 与 HashMap 相同,Hashtable 也不能保证其中 key 和 value 对的顺序
⑷ 与 HashMap 相同,判断两个 key 、value 相等
//使用Properties处理属性文件
@Test
public void test6() throws FileNotFoundException, IOException{
Properties pros = new Properties();
pros.load(new FileInputStream(new File("jdbc.properties")));
String user = pros.getProperty("user");
System.out.println(user);
String password = pros.getProperty("password");
System.out.println(password);
}
五. collections:操作集合的工具类
/*
* reverse(List):反转 List 中元素的顺序
shuffle(List):对 List 集合元素进行随机排序
sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序
sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序
swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换
*/
@Test
public void testCollections1(){
List list = new ArrayList();
list.add(123);
list.add(456);
list.add(12);
list.add(78);
System.out.println(list);
Collections.reverse(list);
System.out.println(list);
Collections.shuffle(list);
System.out.println(list);
Collections.sort(list);
System.out.println(list);
Collections.swap(list, 0, 2);
System.out.println(list);
}
/*
* Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素
Object min(Collection)
Object min(Collection,Comparator)
int frequency(Collection,Object):返回指定集合中指定元素的出现次数
void copy(List dest,List src):将src中的内容复制到dest中
boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值
*/
@Test
public void testCollections2(){
List list = new ArrayList();
list.add(123);
list.add(456);
list.add(12);
list.add(78);
list.add(456);
Object obj = Collections.max(list);
System.out.println(obj);
int count = Collections.frequency(list, 4567);
System.out.println(count);
//实现List的复制
//List list1 = new ArrayList();//错误的实现方式
List list1 = Arrays.asList(new Object[list.size()]);
Collections.copy(list1, list);
System.out.println(list1);
//通过如下的方法保证list的线程安全性。
List list2 = Collections.synchronizedList(list);
System.out.println(list2);
}
六. Enumeration:是 Iterator 迭代器的" 古老版本 "
Enumeration enu = new StringTokenizer("ab-c*-df-g", "-");
while(enu.hasMoreElements()){
System.out.println(enu.nextElement());
}
下一篇: Optional类