在实际的项目中开发过程中,会有很多的对象,如何高效、方便的管理这些对象,是影响程序性能与可维护性的重要环节。在Java语言中为这个问题提供了一套完美的解决方案,也就是接下来要介绍的集合框架。
1.1 集合框架的结构
从Collection接口 继承而来的一般被称为聚焦(有时也被宽泛的称为集合),从Map接口继承来的一般被称为映射。
在Set和Map接口中,都有一个继承自他们的SortedXXX子接口(XXX = Set/Map)
1.2 列表
1.2.1 List(列表)接口
List接口继承自Collection接口,代表列表的功能(角色),其中的元素可以按索引的顺序访问,所以也可以称为有索引的Collection。实现该接口的类均属于Ordered
类型,具有列表的功能,其元素顺序均是按照添加(索引)的先后进行排列的
List接口的常用方法
(略)
与数组一样,列表中的索引是从0开始的,实现了List接口的类也可以被看做可变长度的数组来使用。
List接口中的方法很注重索引。如果开发人员需要对其中每个元素的插入位置进行精准的控制,并且需要根据元素的整数索引访问元素,或搜索列表中的元素,则可以使用实现了该类的接口类。
1.2.2 数组实现列表
ArrayList,是List接口最常用的实现之一。可以向其中添加包括null值在内的所有对象引用型的元素。甚至该对象引用自己也可以作为其中的元素。这样可以方便的搭建一个树状结构的集合。
该类内部类实际上是依赖数组实现的,因此对元素进行随机访问的性能很好,但如果进行大量的插入、删除操作,该类性能很差,
ArrayList中,功能方法大都实现自List接口。
package list;import java.util.ArrayList;//一个使用ArrayList的例子
public class Sample1 {
public static void main(String[] args) {//创建列表ArrayList对象ArrayList al = new ArrayList(); //初始化ArrayList中的元素for(int i = 0;i<50;i++) {al.add(String.valueOf(i));}//对arrlist进行操作for(int i = 60;i<75;i++) {al.set(i-45, String.valueOf(i));}//打印ArrayList列表里的内容System.out.println("这是ArrayList操作后的结果:");System.out.println(al);//取出指定元素并进行处理Object o = al.get(22);String s = (String)o;System.out.println("索引为22的元素长度为:"+s.length());}
}
- 将ArrayList中从索引15开始之后长度为15区间内的元素依次设置为数字60~74的字符串,
- 头文件:java.util.*
- 在没有使用泛型的情况下,无论放进集合的是什么元素,取出的都是Object类型的引用,
ArrayList中并不真正存放对象,而只是存放对象的引用,所有集合框架中的类都如此
1.3 链接实现列表
指LinkedList类,功能与ArrayList类相同,都是列表List的实现。由于其内部是依赖双链表来实现的,因此具有很好的插入、删除性能。但随机访问元素相对较差。适合用在插入、删除多,元素随机访问少的场合。
package list;import java.util.LinkedList;public class Sample2 {public static void main(String[] args) {//创建列表LinkedList对象LinkedList ll = new LinkedList();//初始化LinkedList对象for(int i = 0;i<50;i++) {ll.add(String.valueOf(i));}//对LinkedList进行插入操作for(int i = 15;i<30;i++) {ll.add(i,String.valueOf(30-i+15));}//打印LinkedList列表System.out.println("这是LinkedList操作后的结果");System.out.println(ll);}}
在LinkedList索引为15的地方插入15个元素,其中内容为30-16的字符串。
1.3.1 依赖性倒置原理
依赖项倒置原理:依赖应尽量在抽象层进行,避免在具体层进行。
在实际开发中的含义就是应该尽量使用接口类型的引用,避免使用具体类型的引用。
package list;import java.util.LinkedList;
import java.util.List;
import java.util.Vector;public class MyClass {//声明具体类类型的引用public LinkedList firstList = new LinkedList();//声明具体类类型入口参数的方法public void printLinkedList(LinkedList ll) {System.out.println(ll);}//声明接口类型的引用public List lastList = new Vector();//声明接口类型入口参数的方法public void printAllKindsOfList(List l) {System.out.println(l);}}
-firstList是具体类类型的引用,在未来如果需要改变为其他类型,则会严重影响依赖他的代码。而LastList是接口类型的引用,在未来如果需要,可以指向任何实现了该接口的
package com.hspedu.homework;import java.util.ArrayList;/*** @author 韩顺平* @version 1.0*/
@SuppressWarnings({"all"})
public class Homework01 {public static void main(String[] args) {ArrayList arrayList = new ArrayList();arrayList.add(new News("新冠确诊病例超千万,数百万印度教信徒赴恒河\"圣浴\"引民众担忧"));arrayList.add(new News("男子突然想起2个月前钓的鱼还在网兜里,捞起一看赶紧放生"));int size = arrayList.size();for (int i = size - 1; i >= 0; i--) {//System.out.println(arrayList.get(i));News news = (News)arrayList.get(i);System.out.println(processTitle(news.getTitle()));}}//专门写一个方法,处理现实新闻标题 process处理public static String processTitle(String title) {if(title == null) {return "";}if(title.length() > 15) {return title.substring(0, 15) + "..."; //[0,15)} else {return title;}}
}/*** 按要求实现:* (1) 封装一个新闻类,包含标题和内容属性,提供get、set方法,重写toString方法,打印对象时只打印标题;* (2) 只提供一个带参数的构造器,实例化对象时,只初始化标题;并且实例化两个对象:** 新闻一:新冠确诊病例超千万,数百万印度教信徒赴恒河“圣浴”引民众担忧* 新闻二:男子突然想起2个月前钓的鱼还在网兜里,捞起一看赶紧放生* (3) 将新闻对象添加到ArrayList集合中,并且进行倒序遍历;* (4) 在遍历集合过程中,对新闻标题进行处理,超过15字的只保留前15个,然后在后边加“…”* (5) 在控制台打印遍历出经过处理的新闻标题;*/
class News {private String title;private String content;public News(String title) {this.title = title;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}@Overridepublic String toString() {return "News{" +"title='" + title + '\'' +'}';}
}
public class Homework02 {public static void main(String[] args) {ArrayList arrayList = new ArrayList();Car car = new Car("宝马", 400000);Car car2 = new Car("宾利",5000000);//1.add:添加单个元素arrayList.add(car);arrayList.add(car2);System.out.println(arrayList);//* 2.remove:删除指定元素arrayList.remove(car);System.out.println(arrayList);//* 3.contains:查找元素是否存在System.out.println(arrayList.contains(car));//F//* 4.size:获取元素个数System.out.println(arrayList.size());//1//* 5.isEmpty:判断是否为空System.out.println(arrayList.isEmpty());//F//* 6.clear:清空//System.out.println(arrayList.clear(););//* 7.addAll:添加多个元素System.out.println(arrayList);arrayList.addAll(arrayList);//2个宾利System.out.println(arrayList);//* 8.containsAll:查找多个元素是否都存在arrayList.containsAll(arrayList);//T//* 9.removeAll:删除多个元素//arrayList.removeAll(arrayList); //相当于清空//* 使用增强for和 迭代器来遍历所有的car , 需要重写 Car 的toString方法for (Object o : arrayList) {System.out.println(o);//}System.out.println("===迭代器===");Iterator iterator = arrayList.iterator();while (iterator.hasNext()) {Object next = iterator.next();System.out.println(next);}}
}
/*** 使用ArrayList 完成对 对象 Car {name, price} 的各种操作* 1.add:添加单个元素* 2.remove:删除指定元素* 3.contains:查找元素是否存在* 4.size:获取元素个数* 5.isEmpty:判断是否为空* 6.clear:清空* 7.addAll:添加多个元素* 8.containsAll:查找多个元素是否都存在* 9.removeAll:删除多个元素* 使用增强for和 迭代器来遍历所有的car , 需要重写 Car 的toString方法*/
class Car {private String name;private double price;public Car(String name, double price) {this.name = name;this.price = price;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}@Overridepublic String toString() {return "Car{" +"name='" + name + '\'' +", price=" + price +'}';}
}
import java.util.*;/*** 按要求完成下列任务* 1)使用HashMap类实例化一个Map类型的对象m,键(String)和值(int)分别用于存储员工的姓名和工资,* 存入数据如下: jack—650元;tom—1200元;smith——2900元;** 2)将jack的工资更改为2600元** 3)为所有员工工资加薪100元;* 4)遍历集合中所有的员工* 5)遍历集合中所有的工资*/public class HomeWork04 {public static void main(String[] args) {HashMap hashMap = new HashMap();hashMap.put("jack",650);hashMap.put("tom",1200);hashMap.put("smith",2900);System.out.println(hashMap);hashMap.put("jack",2600);System.out.println(hashMap);//--------------------------------------Set set = hashMap.keySet();//获得key值for (Object key : set) {hashMap.put(key,(Integer)hashMap.get(key)+100);}System.out.println(hashMap);//=================================System.out.println("==========遍历==========");//遍历EntrySetSet entrySet = hashMap.entrySet();//迭代器Iterator iterator = entrySet.iterator();while (iterator.hasNext()) {Map.Entry next = (Map.Entry)iterator.next();System.out.println(next.getKey()+"--"+next.getValue());}System.out.println("=========遍历所有工资========");Collection values = hashMap.values();for (Object value : values) {System.out.println("工资="+value);}}
}
会。
//add 方法,因为 TreeSet() 构造器没有传入Comparator接口的匿名内部类
// 所以在底层 Comparable<? super K> k = (Comparable<? super K>) key;
// 即 把 Perosn转成 Comparable类型treeSet.add(new Personn());//ClassCastException.
// treeSet.add(new Personn());//ClassCastException.
// treeSet.add(new Personn());//ClassCastException.
// treeSet.add(new Personn());//ClassCastException.
// treeSet.add(new Personn());//ClassCastException.System.out.println(treeSet);}
}只有一个person
因为返回值为0.解决错误方法:写一个方法实现接口。
//class Personn implements Comparable{
//
// @Override
// public int compareTo(Object o) {
// return 0;
// }
//}
新创建了两个Person对象,并放入HashSet中。重写p1的name方法。
此时因为name发生变化,找不到P1。修改不了。输出p1、 p2.
再加入一个1001,CC,HashSet将找寻相同的元素。找不到,所以加到后面,输出,三个元素
再加入一个新的1001,AA。HashMap没有在已有的Map中找到相同的元素。所以会输出4个元素
参考
Java中Map的 entrySet() 详解以及用法(四种遍历map的方式)