06java进阶——集合框架(list和泛型)
1.ArrayList
ArrayList集合是程序中最常见的一种集合,它属于引用数据类型(类)。在ArrayList内部封装了一个长度可变的数组,当存入的元素超过数组长度时,ArrayList会在内存中分配一个更大的数组来存储这些元素,因此可以将ArrayList集合看作一个长度可变的数组。
1.1ArrayList的创建
导包:import java.util.ArrayList;
创建对象:与其他普通的引用数据类型创建方式完全相同,但是要指定容器中存储的数据类型:
ArrayList<要存储元素的数据类型> 变量名 = new ArrayList<要存储元素的数据类型>();
- 集合中存储的元素,只能为<>括号中指定的数据类型元素;
- “<要存储元素的数据类型>”中的数据类型必须是引用数据类型,不能是基本数据类型;
下面给出8种基本数据类型所对应的引用数据类型表示形式:
我们通过举几个例子,来明确集合的创建方式:
- 存储String类型的元素
ArrayList<String> list = new ArrayList<String>();
- 存储int类型的数据
ArrayList<Integer> list = new ArrayList<Integer>();
- 存储Phone类型的数据
ArrayList<Phone> list = new ArrayList<Phone>();
1.2常用的方法
package cn.jxufe.java.chapter6; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; public class TestArrayList01 { public static void main(String[] args) {
// TODO Auto-generated method stub
// 创建ArrayList集合
ArrayList<String> list1 = new ArrayList<String>();// 第二个可以省略
// 向集合中添加元素 list1.add("stu1");
list1.add("stu2");
list1.add("stu3");
list1.add("stu4");
// 获取集合中元素的个数
// 取出并打印指定位置的元素
System.out.println("第2个元素是:" + list1.get(1));
System.out.println("list1中的元素为:");
System.out.println(list1);
System.out.println("去除索引值为2的元素后,list中的元素为");
list1.remove(2);
System.out.println(list1);
System.out.println("在索引值为1的元素处添加一个student元素:");
list1.add(1, "student");
System.out.println(list1);
System.out.println("把索引位置为3的元素置为good:");
list1.set(3, "good");
System.out.println(list1);
// 集合的遍历
System.out.println("集合的遍历方法1:");
for (String e : list1) {
System.out.print(e + " ");
}
System.out.println("\n集合的遍历方法2: ");
for (int i = 0; i < list1.size(); i++) {
System.out.print(list1.get(i) + " ");
}
System.out.println("\nlist1是否为空:");
System.out.println(list1.isEmpty());
System.out.println("list1是否包涵good:");
System.out.println(list1.contains("good")); ArrayList<String> list2 = new ArrayList<>();
list2.add("stu1");
list2.add("stu2");
System.out.println("list2中的元素为:");
System.out.println(list2);
System.out.println("从list1中移除list2中的全部元素");
list1.removeAll(list2);// 获得两个集合元素的差集
System.out.println(list1);
System.out.println("list1添加list2中的全部元素");
list1.addAll(list2);// 获得两个集合元素的并集
System.out.println(list1); List<String> list3 = new ArrayList<String>();
list3.add("第一个元素"); // 向列表中添加数据
list3.add("第二个元素"); // 向列表中添加数据
list3.add("第三个元素"); // 向列表中添加数据
List<String> list4 = new ArrayList<String>();
list4.add("第一个元素"); // 向列表中添加数据
list4.add("第三个元素"); // 向列表中添加数据
System.out.println("--------测试retainAll的使用------------:");
boolean ret = list3.retainAll(list4); // 获得两集合相交的元素
System.out.println(ret);
System.out.println(list3); // 创建迭代器
Iterator<String> it = list3.iterator();
// 循环遍历迭代器
System.out.println("循环遍历迭代器:");
while (it.hasNext()) {
System.out.println(it.next()); // 输出集合中元素
} ArrayList<String> list5 = new ArrayList<>();
ArrayList<String> list6 = new ArrayList<>();
list5.add("a");
list5.add("b");
list5.add("c");
list6.add("b");
list6.add("c");
list6.add("d");
list5.retainAll(list6);// 获得两集合相交的元素
System.out.println(list5);
}
}
查看ArrayList类发现它继承了抽象类AbstractList同时实现接口List,而List接口又继承了Collection接口。Collection接口为最顶层集合接口了。
源代码:
interface List extends Collection {
}
public class ArrayList extends AbstractList implements List{
}
集合继承体系
这说明我们在使用ArrayList类时,该类已经把所有抽象方法进行了重写。那么,实现Collection接口的所有子类都会进行方法重写。
- Collecton接口常用的子接口有:List接口、Set接口
- List接口常用的子类有:ArrayList类、LinkedList类
- Set接口常用的子类有:HashSet类、LinkedHashSet类
2.迭代器
java中提供了很多个集合,它们在存储元素时,采用的存储方式不同。我们要取出这些集合中的元素,可通过一种通用的获取方式来完成。
Collection集合元素的通用获取方式:在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。
package cn.jxufe.java.chapter6; import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator; public class TestIterator03 {
/*
* 集合中的迭代器: 获取集合中元素方式 接口 Iterator : 两个抽象方法 boolean hasNext()
* 判断集合中还有没有可以被取出的元素,如果有返回true next() 取出集合中的下一个元素
*
* Iterator接口,找实现类. Collection接口定义方法 Iterator iterator() ArrayList
* 重写方法iterator(),返回了Iterator接口的实现类的对象 使用ArrayList集合的对象 Iterator
* it=array.iterator(),运行结果就是Iterator接口的实现类的对象 it是接口的实现类对象,调用方法 hasNext 和 next
* 集合元素迭代
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Collection<String> coll = new ArrayList<String>();
coll.add("abc1");
coll.add("abc2");
coll.add("abc3");
coll.add("abc4");
// 迭代器,对集合ArrayList中的元素进行取出 // 调用集合的方法iterator()获取出,Iterator接口的实现类的对象
Iterator<String> it = coll.iterator();
// 接口实现类对象,调用方法hasNext()判断集合中是否有元素
// boolean b = it.hasNext();
// System.out.println(b);
// 接口的实现类对象,调用方法next()取出集合中的元素
// String s = it.next();
// System.out.println(s); // 迭代是反复内容,使用循环实现,循环的条件,集合中没元素, hasNext()返回了false
while (it.hasNext()) {
String s = it.next();
System.out.println(s);
}
System.out.println();
// for循环的方式进行遍历,for没有while好理解,但是节约点内存,因为while的it是在main函数中建立的,for的it是在for中建立的
for (Iterator<String> it2 = coll.iterator(); it2.hasNext();) {
System.out.println(it2.next());
}
} }
3.集合迭代中的转型
存储时提升了Object。取出时要使用元素的特有内容,必须向下转型。
package cn.jxufe.java.chapter6; import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator; public class TestCollection04 { public static void main(String[] args) {
// TODO Auto-generated method stub
Collection coll = new ArrayList();
coll.add("abc");
coll.add("aabbcc");
coll.add("shitcast");
Iterator it = coll.iterator();
while (it.hasNext()) {
// 由于元素被存放进集合后全部被提升为Object类型
// 当需要使用子类对象特有方法时,需要向下转型
String str = (String) it.next();
System.out.println(str.length());
}
// 注意:如果集合中存放的是多个对象,这时进行向下转型会发生类型转换异常。
} }
4.泛型
4.1泛型的引入
在前面学习集合时,我们都知道集合中是可以存放任意对象的,只要把对象存储集合后,那么这时他们都会被提升成Object类型。当我们在取出每一个对象,并且进行相应的操作,这时必须采用类型转换。比如下面程序:
package cn.jxufe.java.chapter6; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; public class TestGeneric05 { public static void main(String[] args) {
// TODO Auto-generated method stub
List list = new ArrayList();
list.add("abc");
list.add("itcast");
list.add(5);// 由于集合没有做任何限定,任何类型都可以给其中存放
// 相当于:Object obj=new Integer(5); Iterator it = list.iterator();
while (it.hasNext()) {
// 需要打印每个字符串的长度,就要把迭代出来的对象转成String类型
String str = (String) it.next();// String str=(String)obj;
// 编译时期仅检查语法错误,String是Object的儿子可以向下转型
// 运行时期String str=(String)(new Integer(5))
// String与Integer没有父子关系所以转换失败
// 程序在运行时发生了问题java.lang.ClassCastException
System.out.println(str.length());
}
}
}
4.2泛型的定义和使用
泛型: 指明了集合中存储数据的类型 <数据类型>
上面已经使用了
4.3Java中的伪泛型
泛型只在编译时存在,编译后就被擦除,在编译之前我们就可以限制集合的类型,起到作用
例如:ArrayList<String> al=new ArrayList<String>();
编译后:ArrayList al=new ArrayList();
4.4泛型类
a:定义格式:
修饰符 class 类名<代表泛型的变量> { } 例如,API中的ArrayList集合:
class ArrayList<E>{
public boolean add(E e){ }
public E get(int index){ }
}
b:使用格式:
创建对象时,确定泛型的类型 例如,ArrayList<String> list = new ArrayList<String>();
此时,变量E的值就是String类型
class ArrayList<String>{
public boolean add(String e){ }
public String get(int index){ }
} 例如,ArrayList<Integer> list = new ArrayList<Integer>();
此时,变量E的值就是Integer类型
class ArrayList<Integer>{
public boolean add(Integer e){ }
public Integer get(int index){ }
}
package cn.jxufe.java.chapter6; import java.util.ArrayList; public class GenericStack07<E> { ArrayList<E> list = new ArrayList<>(); public int getSize() {
return list.size();
} public E peek() {
return list.get(getSize() - 1);
} public E pop() {
E o = list.get(getSize() - 1);
list.remove(getSize() - 1);
return o;
} public boolean isEmpty() {
return list.isEmpty();
} public void push(E e) {
list.add(e);
} @Override
public String toString() {
// TODO Auto-generated method stub
return "stack: " + list.toString();
} public static void main(String[] args) {
GenericStack07<String> stack1 = new GenericStack07<>();
stack1.push("good");
stack1.push("good");
stack1.push("study");
System.out.println(stack1); GenericStack07<Integer> stack2 = new GenericStack07<>();
stack2.push(123);
stack2.push(456);
stack2.push(789);
System.out.println(stack2);
}
}
4.5泛型的方法
- a:定义格式:修饰符 <代表泛型的变量> 返回值类型 方法名(参数){ }
- b:泛型方法的使用:
例如,API中的ArrayList集合中的方法:
public <T> T[] toArray(T[] a){ }
//该方法,用来把集合元素存储到指定数据类型的数组中,返回已存储集合元素的数组 使用格式:调用方法时,确定泛型的类型
例如:
ArrayList<String> list = new ArrayList<String>();
String[] arr = new String[100];
String[] result = list.toArray(arr);
此时,变量T的值就是String类型。变量T,可以与定义集合的泛型不同
public <String> String[] toArray(String[] a){ } 例如:
ArrayList<String> list = new ArrayList<String>();
Integer[] arr = new Integer[100];
Integer [] result = list.toArray(arr); 此时,变量T的值就是Integer类型。变量T,可以与定义集合的泛型不同
public <Integer> Integer[] toArray(Integer[] a){ }
使用泛型类型来定义泛型方法
package cn.jxufe.java.chapter6; public class TestGenericMethod { public static void main(String[] args) {
// TODO Auto-generated method stub
Integer[] integers = { 1, 2, 3, 4, 5 };
String[] strings = { "london", "xuzhou", "nanchang" };
print(integers);
print(strings);
} public static <E> void print(E[] list) {
for (E e : list) {
System.out.print(e + " ");
}
System.out.println();
} }
4.6泛型的接口
/*
* 带有泛型的接口
*
* public interface List <E>{
* abstract boolean add(E e);
* }
*
* 实现类,先实现接口,不理会泛型
* public class ArrayList<E> implements List<E>{
* }
* 调用者 : new ArrayList<String>() 后期创建集合对象的时候,指定数据类型
*
*
* 实现类,实现接口的同时,也指定了数据类型
* public class XXX implements List<String>{
* }
* new XXX()
*/
4.7受限的泛型类型
可以将泛型指定为另一种类型的子类型,这样的泛型类型称为受限的。
package cn.jxufe.java.chapter6; abstract class GeometricObject {
public abstract double getArea();
} class Rectangle extends GeometricObject {
double length;
double hight; public Rectangle(double length, double hight) {
// TODO Auto-generated constructor stub
this.length = length;
this.hight = hight;
} public double getArea() {
return length * hight;
}
} class Circle extends GeometricObject {
double radius; public Circle(double radius) {
// TODO Auto-generated constructor stub
this.radius = radius;
} public double getArea() {
return 3.14 * radius * radius;
}
} public class TestBoundedType { public static void main(String[] args) {
// TODO Auto-generated method stub
Rectangle rectangle = new Rectangle(2, 2);
Rectangle rectangle2 = new Rectangle(2, 2);
Circle circle = new Circle(2);
System.out.println(equalArea(rectangle, circle));
System.out.println(equalArea(rectangle, rectangle2));
} public static <E extends GeometricObject> boolean equalArea(E object1, E object2) {
return object1.getArea() == object2.getArea();
} }
4.8示例学习:对一个对象数组进行排序
package cn.jxufe.java.chapter6; public class TestGenericSort { public static void main(String[] args) {
// TODO Auto-generated method stub
Integer[] intArray = { new Integer(2), new Integer(4), new Integer(3) };
Double[] doubleArray = { new Double(3.4), new Double(1.3), new Double(-22.1) };
Character[] charArray = { new Character('a'), new Character('c'), new Character('b') };
String[] stringArray = { "tom", "jack", "blue" };
sort(intArray);
sort(doubleArray);
sort(charArray);
sort(stringArray); System.out.println("sorted integer objects:");
printList(intArray);
System.out.println("sorted double objects:");
printList(doubleArray);
System.out.println("sorted charArray objects:");
printList(charArray);
System.out.println("sorted stringArray objects:");
printList(stringArray);
} public static <E extends Comparable<E>> void sort(E[] list) {
E currentMin;
int currentMinIndex;
for (int i = 0; i < list.length - 1; i++) {
currentMin = list[i];
currentMinIndex = i;
for (int j = i + 1; j < list.length; j++) {
if (currentMin.compareTo(list[j]) > 0) {
currentMin = list[j];
currentMinIndex = j;
}
}
if (currentMinIndex != i) {
list[currentMinIndex] = list[i];
list[i] = currentMin;
}
}
} public static void printList(Object[] list) {
for (int i = 0; i < list.length; i++) {
System.out.print(list[i] + " ");
}
System.out.println();
} }
4.9泛型的好处
- 将运行时期的ClassCastException,转移到了编译时期变成了编译失败。
- 避免了类型强转的麻烦。
4.10泛型的通配符
package cn.jxufe.java.chapter6; public class TestWildCard { public static void main(String[] args) {
// TODO Auto-generated method stub
GenericStack07<Integer> intStack = new GenericStack07<>();
intStack.push(1);
intStack.push(2);
intStack.push(-1); System.out.println("the max number is " + max(intStack));//编译会报错,因为intStack不是GenericStack<Number>的实例
} public static double max(GenericStack07<Number> stack) {
double max = stack.pop().doubleValue();
while (!stack.isEmpty()) {
double value = stack.pop().doubleValue();
if (value > max)
max = value;
}
return max;
} }
package cn.jxufe.java.chapter6; public class TestWildCard { public static void main(String[] args) {
// TODO Auto-generated method stub
GenericStack07<Integer> intStack = new GenericStack07<>();
intStack.push(1);
intStack.push(2);
intStack.push(-1); System.out.println("the max number is " + max(intStack));//编译会报错,因为intStack不是GenericStack<Number>的实例
} public static double max(GenericStack07<? extends Number> stack) {
double max = stack.pop().doubleValue();
while (!stack.isEmpty()) {
double value = stack.pop().doubleValue();
if (value > max)
max = value;
}
return max;
} }
package cn.jxufe.java.chapter6; public class TestAnyWild { public static void main(String[] args) {
// TODO Auto-generated method stub
GenericStack07<Integer> intStack = new GenericStack07<>();
intStack.push(1);
intStack.push(2);
intStack.push(-2);
print(intStack); GenericStack07<String> stringStack = new GenericStack07<>();
stringStack.push("zhangSan");
stringStack.push("zhaoSi");
stringStack.push("wangWu");
print(stringStack); } public static void print(GenericStack07<?> stack) {
while (!stack.isEmpty()) {
System.out.print(stack.pop() + " ");
}
System.out.println();
} }
package cn.jxufe.java.chapter6; import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator; public class TestWildcard06 { public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<String> array = new ArrayList<String>(); HashSet<Integer> set = new HashSet<Integer>(); array.add("123");
array.add("456"); set.add(789);
set.add(890); iterator(array);
iterator(set);
} /*
* 定义方法,可以同时迭代2个集合 参数: 怎么实现 , 不能写ArrayList,也不能写HashSet 参数: 或者共同实现的接口
* 泛型的通配,匹配所有的数据类型 ?
*/
public static void iterator(Collection<?> coll) {
Iterator<?> it = coll.iterator();
while (it.hasNext()) {
// it.next()获取的对象,什么类型
System.out.println(it.next());
}
}
}
package cn.jxufe.java.chapter6; public class TestSuperWildChard { public static void main(String[] args) {
// TODO Auto-generated method stub
GenericStack07<String> stack1 = new GenericStack07<>();
GenericStack07<Object> stack2 = new GenericStack07<>();
stack2.push("java");
stack2.push(2);
stack1.push("sun");
add(stack1, stack2);
TestAnyWild12.print(stack2);
} public static <T> void add(GenericStack07<T> stack1, GenericStack07<? super T> stack2) {
while (!stack1.isEmpty()) {
stack2.push(stack1.pop());
}
} }
06java进阶——集合框架(list和泛型)的更多相关文章
- Java基础之集合框架类及泛型简介
Collection接口 Collection 通用的常见方法 add()添加一个元素,可以指定脚标 addAll()将一个collection放入 clear()清除 remove()删除元素,返回 ...
- Java学习笔记29(集合框架三:泛型)
泛型的概念: 简单地讲,就是同一个方法(类),可以接受不同的数据类型并运行得到相对应的结果,不会出现安全问题 上一篇有一段这样的代码: 没有定义集合类型.迭代器类型 package demo; imp ...
- 07java进阶——集合框架3(Map)
1.映射表(Map) 1.1基本概念 1.2Map中常用的方法 package cn.jxufe.java.chapter7; import java.util.HashMap; import jav ...
- 07java进阶——集合框架(set)
1.list接口中常用的特有方法 package cn.jxufe.java.chapter7; import java.util.ArrayList; import java.util.List; ...
- Java使用实现面向对象编程:第七章集合框架的解读=>重中之重
对于集合框架,是非常重要的知识,是程序员必须要知道的知识点. 但是我们为什么要引入集合框架呢? 我们之前用过数组存储数据,但是采用数组存储存在了很多的缺陷.而现在我们引用了集合框架,可以完全弥补了数组 ...
- Java面试准备之集合框架
集合框架 Collection:List列表,Set集 Map:Hashtable,HashMap,TreeMap Collection 是单列集合 List 元素是有序的(元素存取是有序).可重复 ...
- Java 集合框架部分面试题
1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最初的Java版本包含几种集合类:Vector.Stack.HashTable和Array.随着集合的广泛使用,Java1 ...
- Java 集合框架 02
集合框架· LinkedList 和 泛型 去除ArrayList中重复字符串元素 * A:案例演示 * 需求:ArrayList去除集合中字符串的重复值(相同内容的字符串) * 思路:创建新集合方式 ...
- 一起学 Java(三) 集合框架、数据结构、泛型
一.Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含如下内容: 接口:是代表集合的抽象数据类型.接口允许集合独立操纵其代表的细节.在面向对象的语言,接口通常形成一个 ...
随机推荐
- CANopen的相关学习
CANopen是一种架构在控制局域网路(Controller Area Network, CAN)上的高层通讯协定,包括通讯子协定及设备子协定常在嵌入式系统中使用,也是工业控制常用到的一种现场总线. ...
- MAC安装navcat
安装及破解,参照此文: https://blog.csdn.net/marswill/article/details/79808416
- 前端必须掌握的 docker 技能(1)
概述 作为一个前端,我觉得必须要学会使用 docker 干下面几件事: 部署前端应用 部署 nginx 给部署的 nginx 加上 https 使用 docker compose 进行部署 给 ngi ...
- 3.k8s资源控制器rs Deployment Job
k8s资源控制器 #控制器类型 ReplicaSet #rs,确保pod副本数,rs已替代rc Deployment #管理rs,升级.回滚.扩容pod DaemonSet #在每个节点运行一个Pod ...
- win10 iis部署后 浏览目录报错 500.19
错误摘要HTTP 错误 500.19 - Internal Server Error无法访问请求的页面,因为该页的相关配置数据无效.详细错误信息模块 IIS Web Core 通知 BeginReq ...
- Linux的远程桌面折腾指南
因为实验服务器需要远程提供给研一童鞋使用,这两天折腾了一下Linux的远程桌面,在此记录总结一下.服务器系统为Lubuntu 16.04 远程登录到Linux 方案一:简单使用--x11vnc 单用户 ...
- yum 下载rpm包 安装rpm包依赖关系
方法一:yumdownloader 工具 1.安装工具包 yum install yum-utils -y 2.下载一个RPM包 yumdownloader <package-name> ...
- 【Linux开发】【Qt开发】ARM QT移植详细步骤教程
ARM QT移植详细步骤教程 米尔SAM9X5和A5D3X上默认的Qt版本是4.5.3,当这个版本的Qt库不能满足实际开发需求时,可通过此方法制定Qt开发.运行环境. 移植的步骤如下: 1.下载新版q ...
- Linux 项目上线流程
命令行样式修改 1 打开配置文件vim /etc/bashrc2 添加配置信息PS1="\[\e[37;40m\][\[\e[32;1m\]\u\[\e[37;40m\]@\h \[\e[3 ...
- 安装配置php及fastadmin
FastAdmin教程之准备运行环境 一.Node.js http://nodejs.cn/download/ https://npm.taobao.org/mirrors/node/v8.4.0 ...