在实际的项目中开发过程中,会有很多的对象,如何高效、方便的管理这些对象,是影响程序性能与可维护性的重要环节。在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;
}
@Override
public 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;
}
@Override
public 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("==========遍历==========");
//遍历EntrySet
Set 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的方式)