概述
第十三章 Java类集框架
13.1 类集概念
类集在整个Java中最为核心的用处就在于其实现了动态对象数组的操作,并且定义了大量的操作标准。
在整个类集框架中,其核心接口为:Collection、List、Set、Map、Iterator、Enumeration。
13.2 单对象保存父接口:Collection
即每次利用Collection接口都只能保存一个对象信息。
核心方法
NO. | 方法名称 | 类型 | 描述 |
---|---|---|---|
1 | public boolean add(E e) | 普通 | 向集合里面保存数据 |
2 | public boolean add.All(Collection<?extends E>c) | 普通 | 追加一个集合 |
3 | public void clear() | 普通 | 清空集合,根元素为null |
4 | public boolean contains(Object o) | 普通 | 判断是否包含指定的内容,需要equals()支持 |
5 | public boolean isEmpty() | 普通 | 判断是否是空集合(不是null) |
6 | public boolean remove(Object o) | 普通 | 删除对象,需要equals()支持 |
7 | public int size() | 普通 | 取得集合中保存的元素个数 |
8 | public Object[] toArray() | 普通 | 将集合变为对象数组保存 |
9 | public Iteratoriterator() | 普通 | 为Iterator接口实例化 |
在所以方法中最重要的就是add()和iterator()两个方法,同时在使用contains()与remove()两个方法的操作时,必须保证类中已经成功地覆写了Object类中的equals()方法。
13.3 List子接口
里面所保存的数据可以存在重复内容
扩充的方法
public E get(int index):取得索引编号的内容
public E set(int index,E element):修改指定索引编号的内容
public ListIteratorlistIterator():为ListIterator接口实例化
13.3.1 新的子类:ArrayList
List基本操作
public class TestDemo {
public static void main(String[] args) throws Exception {
List<String>all=new ArrayList<String>();
System.out.println("长度:"+all.size()+",是否为空:"+all.isEmpty());
all.add("Hello");
all.add("Hello");
all.add("World");
System.out.println("长度:"+all.size()+",是否为空:"+all.isEmpty());
for (int x=0;x<all.size();x++){
String str=all.get(x);
System.out.println(str);
}
}
}
常见面试题
数组(Array)与数组列表(ArrayList)有什么区别?什么时候应该使用Array而不使用ArrayList?
数组Array中保存的内容是固定的,而数组列表(ArrayList)中保存的内容是可变的。在很多时候(ArrayList)进行数据保存与取得时需要一系列的判断,而如果是数组Array只需要操作索引即可。
如果在已经确定好长度的前提下,完全可以使用数组(Array)来替代数组列表,但是如果集合框架保存的数据内容长度是不固定的,那么就使用ArrayList。
在集合里面保存对象
import java.io.Serializable;
public class Book implements Serializable {
private String title;
private double price;
public Book(String title,double price){
this.title=title;
this.price=price;
}
@Override
public boolean equals(Object obj){
if (this==obj){
return true;
}
if (obj==null){
return false;
}
if (!(obj instanceof Book)){
return false;
}
Book book=(Book) obj;
if (this.title.equals(book.title)&&this.price==book.price){
return true;
}
return false;
}
@Override
public String toString(){
return "书名:"+this.title+"价格:"+this.price;
}
}
public class TestDemo {
public static void main(String[] args) {
List<Book>all=new ArrayList<Book>();
all.add(new Book("Java实战项目",19.9));
all.add(new Book("Jav实战项目",29.9));
all.add(new Book("Ja实战项目",39.9));
all.remove(new Book("朱小东自传",89.5));
System.out.println(all);
}
}
instanceof
instanceof是Java中的二元运算符,左边是对象,右边是类;当对象是右边类或子类所创建对象时,返回true;否则,返回false。
这里说明下:
类的实例包含本身的实例,以及所有直接或间接子类的实例
instanceof左边显式声明的类型与右边操作元必须是同种类或存在继承关系,也就是说需要位于同一个继承树,否则会编译错误
请解释ArrayList和LinkedList的区别
- ArrayLis中采用顺序式的结果进行数据的保存,并且可以自动生成相应的索引信息。
- LinkedList集合保存的是前后元素,也就是说像链表一样的结构。
13.3.2 旧的子类:Vector
public class TestDemo {
public static void main(String[] args) {
List<String>all=new Vector<String>();
System.out.println("长度:"+all.size()+",是否为空:"+all.isEmpty());
all.add("Hello");
all.add("Hello");
all.add("World");
System.out.println("长度:"+all.size()+",是否为空:"+all.isEmpty());
for (int x=0;x<all.size();x++){
String str=all.get(x);
System.out.println(str);
}
}
}
13.4 Set子接口
Set子接口只是简单地继承了Collection接口,在Set子接口里面无法使用get()方法根据索引取得保存数据的操作。
两个子类
- HashSet:散列存放数据
- TreeSet:有序存放数据
13.4.1 关于数据排序的说明
TreeSet子类保存的内容可以进行排序,但是其排序是依靠比较器接口(Comparable)实现的。
利用TreeSet保存自定义类对象
public class Book implements Comparable<Book> {
private String title;
private double price;
public Book(String title,double price){
this.title=title;
this.price=price;
}
@Override
public int compareTo(Book o){
if (this.price>o.price){
return 1;
}else if (this.price<o.price){
return -1;
}else {
return this.title.compareTo(o.title);
}
}
@Override
public String toString(){
return "书名:"+this.title+"价格:"+this.price+"n";
}
}
public class TestDemo {
public static void main(String[] args) {
Set<Book> all=new TreeSet<Book>();
all.add(new Book("java实战项目",79.8));
all.add(new Book("Jsp实战项目",55.5));
all.add(new Book("java实战项目",79.8));
all.add(new Book("朱小东自传",55.5));
System.out.println(all);
}
}
13.4.2 关于重复元素说明
如果HashSet要消除重复元素,则必须依靠Object类中提供的两个方法。
- 取得哈希码:public int hashCode();(先判断对象的哈希码是否相同,依靠哈希码取得一个对象的内容)
- 对象比较:public boolean equals(Object obi)(再将对象的属性进行依次的比较)
利用Has和Set子类保存自定义类对象
public class Book {
private String title;
private double price;
public Book(String title,double price){
this.title=title;
this.price=price;
}
@Override
public int hashCode(){
final int prime=31;
int result=1;
long temp;
temp=Double.doubleToLongBits(price);
result=prime*result+(int)(temp^(temp>>>32));
result=prime*result+((title==null)?0:title.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Book other = (Book) obj;
if (Double.doubleToLongBits(price) != Double.doubleToLongBits(other.price))
return false;
if (title == null) {
if (other.title != null)
return false;
} else if (!title.equals(other.title))
return false;
return true;
}
@Override
public String toString(){
return "书名:"+this.title+"价格:"+this.price+"n";
}
}
public class TestDemo {
public static void main(String[] args) {
Set<Book> all=new HashSet<Book>();
all.add(new Book("java实战项目",79.8));
all.add(new Book("Jsp实战项目",55.5));
all.add(new Book("java实战项目",79.8));
all.add(new Book("朱小东自传",55.5));
System.out.println(all);
}
}
在进行非排序集合操作时,只要是判断重复元素依靠的永远都是hashCode()与equals().
13.5 集合输出
集合的输出操作有4种形式:Iterator输出、ListIterator输出、foreach输出、Enumeration输出。
13.5.1 迭代输出:Iterator
hasNext():判断是否还有内容
next():取出当前内容
使用Iterator输出集合
public class TestDemo {
public static void main(String[] args) {
List<String>all=new ArrayList<String>();
all.add("Hello");
all.add("Hello");
all.add("World");
Iterator<String>iter=all.iterator();
while (iter.hasNext()){
String str=iter.next();
System.out.println(str);
}
}
}
13.5.2 双向迭代:Listlterator
hasPrevious():判断是否有前一个元素
previous:取出前一个元素
add(E e):向集合追加数据
set(E e):修改集合数据
在实际开发中一般使用Iterator接口
ListIterator是专门为List子接口定义的输出接口,所以ListIterator接口对象的实例化可以依靠List接口提供方法。
public class TestDemo {
public static void main(String[] args) {
List<String>all=new ArrayList<String>();
all.add("Hello");
all.add("You");
all.add("World");
System.out.println("有前向后输出:");
ListIterator<String>iter=all.listIterator();
while (iter.hasNext()){
String str=iter.next();
System.out.println(str+"、");
}
System.out.println("n由后向前输出:");
while (iter.hasPrevious()){
String str=iter.previous();
System.out.println(str+"、");
}
}
}
13.5.3 foreach输出
public class TestDemo {
public static void main(String[] args) {
List<String>all=new ArrayList<String>();
all.add("Hello");
all.add("You");
all.add("World");
for(String str:all){
System.out.println(str);
}
}
}
13.5.4 Enumeration输出
如何要利用集合类为Enuemration接口实例化,就必须依靠Vector子类完成。
public class TestDemo {
public static void main(String[] args) {
Vector<String>all=new Vector<String>();
all.add("Hello");
all.add("You");
all.add("World");
Enumeration<String>enu=all.elements();
while (enu.hasMoreElements()){
String str=enu.nextElement();
System.out.println(str);
}
}
}
13.6 偶对象保存:Map接口
Map的特点
- 使用HashMap定义的Map集合是无序存放的;
- 如果发现了重复的key会进行覆盖,使用新的内容替换旧的内容。
- 使用HashMap子类保存数据时key或value可以保存为null。
- Map保存数据的目的并不是进行输出操作,而是为了进行查找,即利用get()方法通过key找到对应的value数据。
Map接口的常用方法
public V put(K key,V vaule):向集合中保存数据
public V get(Object key):根据key查找对应的value数据
public Set<Map.Entry<K,V>>entrySet():将Map集合转化为Set集合。
public SetkeySet:取出全部的key
HashMap的使用
public class TestDemo {
public static void main(String[] args) {
Map<String,Integer>map=new HashMap<String,Integer>();
map.put("哈",1);
map.put("哈",1);
map.put("哈哈",null);
map.put("null",1);
map.put("哈哈哈",5);
map.put("哈哈哈哈",null);
System.out.println(map.keySet());
System.out.println(map);
System.out.println(map.get("哈"));
}
}
Collection接口数据是为了输出,Map接口数据是为了查询。
使用Hashtable
public class TestDemo {
public static void main(String[] args) {
Map<String,Integer>map=new Hashtable<String,Integer>();
map.put("哈",1);
map.put("哈哈",null);
map.put(null,1);
map.put("哈哈哈",5);
map.put("哈哈哈哈",null);
System.out.println(map.get("哈"));
}
}
常见面试题分析
区别点 | HashMap | Hashtable |
---|---|---|
推出时间 | JDK1.2推出,属于新类 | JDK1.0时推出,属于旧的类 |
性能 | 采用异步处理 | 采用同步处理 |
数据安全 | 非线程安全 | 线程安全 |
设置null | 允许key或value为空 | 不允许设置null |
13.6.1 利用Iterator输出Map集合
用Map集合保存数据时,所保存的key与value会自动包装为Map.Entry接口对象,也就是说如果利用Iterator进行迭代,那么每当使用next()方法读取数据时返回的都是一个Map.Entry接口对象。
常用方法
getKey():取得数据中的key
getValue():取得数据中的value
setValue(V value):修改数据中的value
public class TestDemo {
public static void main(String[] args) {
Map<String,Integer>map=new Hashtable<String,Integer>();
map.put("哈",1);
map.put("哈哈",null);
map.put(null,1);
map.put("哈哈哈",5);
map.put("哈哈哈哈",null);
Set<Map.Entry<String,Integer>>set=map.entrySet();
Iterator<Map.Entry<String,Integer>>iter=set.iterator();
while (iter.hasNext()){
Map.Entry<String,Integer>me=iter.next();
System.out.println(me.getKey()+"="+me.getValue());
}
}
}
13.6.2 自定义Map集合的key类型
使用自己定义的类作为Map集合的key
public class Book {
private String title;
public Book(String title){
this.title=title;
}
@Override
public int hashCode(){
final int prime=31;
int result=1;
result=prime*result+((title==null)?0:title.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Book other = (Book) obj;
if (title == null) {
if (other.title != null)
return false;
} else if (!title.equals(other.title))
return false;
return true;
}
@Override
public String toString(){
return "书名:"+this.title;
}
}
public class TestDemo {
public static void main(String[] args) {
Map<Book,String >map=new HashMap<Book,String>();
map.put(new Book("java开发"),new String("java"));
System.out.println(map.get(new Book("java开发")));
}
}
13.7 Stack子类
Stack属于一种栈的操作
public E push(E item):数据入栈
public E pop():数据出栈,如果栈中没有数据,则调用此方法会抛出空栈异常。
观察栈的操作
public class TestDemo {
public static void main(String[] args) {
Stack<String>all=new Stack<String>();
all.push("www.baidu.com");
all.push("www.jiangli.com");
all.push("www.douban.com");
System.out.println(all.pop());
System.out.println(all.pop());
System.out.println(all.pop());
System.out.println(all.pop());
}
}
如果栈中没有任何数据时,进行出栈将会抛出异常,EmptyStackException。
13.8 Properties子类
此子类只能保存字符串类型的数据
public Object setProperty(String key,String value):设置属性
public String getProperty(String key):取得属性,如果key不存在则返回null。
public String getProperty(String key,String defaultValue):取得属性,如果key不存在则返回默认值
public void store(OutputStream out,String comments)throws IOException:通过输出流保存属性内容,输出的同时可以设置注释信息。
public void load(InputStream inStream)throws IOException:通过输入流读取属性内容
属性的基本操作
public class TestDemo {
public static void main(String[] args) {
Properties pro=new Properties();
pro.setProperty("BJ","北京");
pro.setProperty("TJ","天津");
System.out.println(pro.getProperty("BJ"));
System.out.println(pro.getProperty("GZ"));
System.out.println(pro.getProperty("GZ","没有此记录"));
}
}
将属性信息保存在文件里
public class TestDemo {
public static void main(String[] args) throws Exception {
Properties pro=new Properties();
pro.setProperty("BJ","北京");
pro.setProperty("TJ","天津");
System.out.println(pro.getProperty("BJ"));
System.out.println(pro.getProperty("GZ"));
System.out.println(pro.getProperty("GZ","没有此记录"));
pro.store(new FileOutputStream(new File("d:"+File.separator+"hhh.properties")),"Area Info");
}
}
通过文件流读取属性内容
public class TestDemo {
public static void main(String[] args) throws Exception {
Properties pro=new Properties();
pro.load(new FileInputStream(new File("d:"+File.separator+"hhh.properties")));
System.out.println(pro.getProperty("BJ"));
}
}
Properties类与ResourceBundle类使用那个更好?
Properties可以读取任意输入流,ResourceBundle类要结合国际化读取*.prperties文件。
如果是国际文件用ResourceBundle,配置信息则用Properties。
13.9 Collections工具类
常用方法
public static < T >boolean addAll(Collection<?super T>c,T…elements):实现集合数据追加
public static < T >int binarySearch(List<?extends Comparable<? super T>>list,T key):使用二分查找法查找集合数据
public static < T >void copy(LIst <?super T>dest,List <?extends T>src):集合复制
public static void reverse(List <?>list):集合反转
public static <T extends Comparable<? super T>>void sort (List list):集合排序
public class TestDemo {
public static void main(String[] args) throws Exception {
List<String>all=new ArrayList<String>();
//利用Collections类的方法向集合保存多个数据
Collections.addAll(all,"jijij","dfaf","dfafdsa","dfafasd");
Collections.reverse(all); //反转
System.out.println(all);
}
}
Collection与Collections的区别
-
Collection是集合操作的接口
-
Collections:是集合操作的工具类
13.10 数据流
13.10.1 数据流基础操作
Stream接口常用方法
NO. | 方法 | 类型 | 描述 |
---|---|---|---|
1 | public long count() | 普通 | 返回元素个数 |
2 | public Streamdistinct() | 普通 | 消除重复元素 |
3 | public <R,A>R collect(Collector<? super T,A,R>collector) | 普通 | 利用收集器接收处理后的数据 |
4 | public Stream< T>filter(Predicate<?super T>predicate) | 普通 | 数据过滤(设置断言型函数式接口) |
5 | public < R >Stream < R >map(Function<? super T,? extends R>mapper) | 普通 | 数据处理操作(设置功能型函数接口) |
6 | public Stream < T >skip (long n) | 普通 | 设置跳过的数据行树 |
7 | public Stream < T >limit (long maxSize) | 普通 | 设置取出的数据个数 |
8 | public boolean allMatch(Preadicate <? super T>predicate) | 普通 | 数据查询,要求全部匹配 |
9 | public boolean anyMatch(Predicate <? super T>predicate) | 普通 | 数据查询,匹配任意一个 |
10 | default Predicate < T > or(Predicate<? super T>other) | 普通 | 或操作 |
11 | default Predicate < T > and(Predicate<? super T>other) | 普通 | 与操作 |
利用forEach()方法输出
public class TestDemo {
public static void main(String[] args) throws Exception {
List<String>all=new ArrayList<String>();
all.add("www.baidu.com");
all.add("www.xiaomi.com");
all.add("www.bilibili.com");
all.forEach(System.out::println);
}
}
取得Stream对象
首先利用stream()方法将集合转化为数据流的形式,然后利用Stream类中的count()方法取得了数据流中所保存的元素个数。
public class TestDemo {
public static void main(String[] args) throws Exception {
List<String>all=new ArrayList<String>();
all.add("www.baidu.com");
all.add("www.xiaomi.com");
all.add("www.bilibili.com");
Stream<String> stream=all.stream();
System.out.println(stream.count());
}
}
取消集合中的重复数据
public class TestDemo {
public static void main(String[] args) throws Exception {
List<String>all=new ArrayList<String>();
all.add("www.baidu.com");
all.add("www.baidu.com");
all.add("www.xiaomi.com");
all.add("www.bilibili.com");
Stream<String> stream=all.stream();
//去掉重复数据后形成新的List集合数据,里面不包含重复内容的集合
List<String>newAll=stream.distinct().collect(Collectors.toList());
newAll.forEach(System.out::println);
}
}
利用filter()方法针对数据流中的数据进行数据过滤的操作,在执行过滤时需要设置一个断言型函数式接口的方法引用。
数据过滤
如何集合中包含“t”则满足过滤条件
public class TestDemo {
public static void main(String[] args) throws Exception {
List<String>all=new ArrayList<String>();
all.add("www.baidu.com");
all.add("www.AHJHH.com");
all.add("www.baidu.com");
all.add("www.xiaomi.com");
all.add("www.bilibili.com");
Stream<String> stream=all.stream();
//去掉重复数据后形成新的List集合数据,里面不包含重复内容的集合,对每条数据统一转为小写
List<String>newAll=stream.distinct().map((x)->x.toLowerCase())
.filter((x)->x.contains("b")).collect(Collectors.toList());
newAll.forEach(System.out::println);
}
}
实现数据流数据的分页操作
此时只需要使用skip()与limit()两个方法控制即可
public class TestDemo {
public static void main(String[] args) throws Exception {
List<String>all=new ArrayList<String>();
all.add("www.JIXIANIT.com");
all.add("www.yootk.com");
all.add("www.yootk.com");
all.add("www.mldn.com");
all.add("www.mldn.com");
Stream<String> stream=all.stream();
//去掉重复数据后形成新的List集合数据,里面不包含重复内容的集合,对每条数据统一转为小写
List<String> newAll=stream.distinct().map((x)->x.toLowerCase())
.filter((x)->x.contains("t")).skip(1).limit(1).collect(Collectors.toList());
newAll.forEach(System.out::println);
}
}
实现数据的匹配查询
public class TestDemo {
public static void main(String[] args) throws Exception {
List<String>all=new ArrayList<String>();
all.add("www.JIXIANIT.com");
all.add("www.yootk.com");
all.add("www.yootk.com");
all.add("www.mldn.com");
all.add("www.mldn.com");
Stream<String> stream=all.stream();
if (stream.anyMatch((x)->x.contains("yootk"))){
System.out.println("数据存在!");
}
}
}
不管使用allMatch()或anyMatch()方法,都只能接收一种数据验证条件,如果要同时匹配多个条件,则可以利用or()或and()方法实现逻辑操作。
设置多个条件
public class TestDemo {
public static void main(String[] args) throws Exception {
List<String>all=new ArrayList<String>();
all.add("www.baidu.com");
all.add("www.AHJHH.com");
all.add("www.baidu.com");
all.add("www.xiaomi.com");
all.add("www.bilibili.com");
Predicate<String> p1=(x)->x.contains("baidu");
Predicate<String> p2=(x)->x.contains("bilibili");
Stream<String> stream=all.stream();
if (stream.anyMatch(p1.or(p2))){
System.out.println("数据存在!");
}
}
}
13.10.2 MapReduce
- public < R > Stream < R > map(Function<? super T,?extends R>mapper):数据处理方法
- public Optional< T > reduce(BinaryOperator< T >accumulator):数据分析方法。
实现一个MapReduce
public class TestDemo {
public static void main(String[] args) throws Exception {
List<Orders>all=new ArrayList<Orders>();
//添加购买记录
all.add(new Orders("java开发",22.33,300));
all.add(new Orders("web开发",32.33,200));
all.add(new Orders("毛泽东自传",222.33,150));
all.add(new Orders("数据结构",42.33,160));
//输出每一个商品的总价
all.stream().map((x)->x.getAmount()*x.getPrice()).forEach(System.out::println);
}
}
- getCount():求和
- getAverage():求平均值
- getCount():求数量
- getMax():求最大值
- getMain():求最小值
最后
以上就是儒雅乐曲为你收集整理的第十三章 Java类集框架第十三章 Java类集框架的全部内容,希望文章能够帮你解决第十三章 Java类集框架第十三章 Java类集框架所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复