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和泛型)的更多相关文章

  1. Java基础之集合框架类及泛型简介

    Collection接口 Collection 通用的常见方法 add()添加一个元素,可以指定脚标 addAll()将一个collection放入 clear()清除 remove()删除元素,返回 ...

  2. Java学习笔记29(集合框架三:泛型)

    泛型的概念: 简单地讲,就是同一个方法(类),可以接受不同的数据类型并运行得到相对应的结果,不会出现安全问题 上一篇有一段这样的代码: 没有定义集合类型.迭代器类型 package demo; imp ...

  3. 07java进阶——集合框架3(Map)

    1.映射表(Map) 1.1基本概念 1.2Map中常用的方法 package cn.jxufe.java.chapter7; import java.util.HashMap; import jav ...

  4. 07java进阶——集合框架(set)

    1.list接口中常用的特有方法 package cn.jxufe.java.chapter7; import java.util.ArrayList; import java.util.List; ...

  5. Java使用实现面向对象编程:第七章集合框架的解读=>重中之重

    对于集合框架,是非常重要的知识,是程序员必须要知道的知识点. 但是我们为什么要引入集合框架呢? 我们之前用过数组存储数据,但是采用数组存储存在了很多的缺陷.而现在我们引用了集合框架,可以完全弥补了数组 ...

  6. Java面试准备之集合框架

    集合框架 Collection:List列表,Set集 Map:Hashtable,HashMap,TreeMap Collection 是单列集合 List 元素是有序的(元素存取是有序).可重复 ...

  7. Java 集合框架部分面试题

    1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最初的Java版本包含几种集合类:Vector.Stack.HashTable和Array.随着集合的广泛使用,Java1 ...

  8. Java 集合框架 02

    集合框架· LinkedList 和 泛型 去除ArrayList中重复字符串元素 * A:案例演示 * 需求:ArrayList去除集合中字符串的重复值(相同内容的字符串) * 思路:创建新集合方式 ...

  9. 一起学 Java(三) 集合框架、数据结构、泛型

    一.Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含如下内容: 接口:是代表集合的抽象数据类型.接口允许集合独立操纵其代表的细节.在面向对象的语言,接口通常形成一个 ...

随机推荐

  1. Laravel提交POST请求报错

    提交POST请求出现如下错误: The page has expired due to inactivity Please refresh and try again 这是由于在Laravel框架中有 ...

  2. java第二周小结

    这是接触Java的第一周,了解这个语言的一些基础知识,下面是对这段时间重要知识点的汇总 一.Java是一种面向对象的语言    特点为:简洁高效.可移植性.适合分布式计算.健壮防患于未然的特性.多线程 ...

  3. 七、chromedriver各版本下载网址

    http://chromedriver.storage.googleapis.com/index.html

  4. python - property 属性函数

    Python中有一个被称为属性函数(property)的小概念,它可以做一些有用的事情.在这篇文章中,我们将看到如何能做以下几点: 将类方法转换为只读属性 重新实现一个属性的setter和getter ...

  5. Openstack 实现技术分解 (2) 虚拟机初始化工具 — Cloud-Init & metadata & userdata

    目录 目录 前文列表 扩展阅读 系统环境 前言 Cloud-init Cloud-init 的配置文件 metadata userdata metadata 和 userdata 的区别 metada ...

  6. CSS3——边框 圆角 背景 渐变 文本效果

    边框 圆角边框 盒阴影 边界图片 圆角 CSS3 圆角制作器 指定每个角 背景 多重背景图像 大小 图像的定位 背景剪裁 渐变 线性渐变(Linear Gradients)- 向下/向上/向左/向右/ ...

  7. 添加linux中svn的用户和密码

    1:首先找到svn路径 find / -iname "svn" 一般找到svn路径之后就可以找到配置文件位置啦 svn/svnrepos/jgcp/conf 2:进入目录之后修改a ...

  8. Vue.js系列:生命周期钩子

    开发人员提供了一个Web开发人员可以在Vue.js应用程序的整个生命周期中使用的各种方法的讨论. 生命周期钩子是在Vue对象生命周期的某个阶段执行的已定义方法.从初始化开始到它被破坏时,对象都会遵循不 ...

  9. vue分别打包测试环境和正式环境

    vue打包时使用不同的环境变量 需求 同一个项目通过打包使用不同的环境变量,目前的环境有三个: 一.本地------开发环境 二.线上------测试环境 三.线上------正式环境 我们都知道vu ...

  10. 20191127 Spring Boot官方文档学习(9.1-9.3)

    9."使用方法"指南 9.1.Spring Boot应用程序 9.1.1.创建自己的FailureAnalyzer FailureAnalyzer被包装在FailureAnalys ...