Java 面向对象(十一)

java

常用类之集合

集合:就是用来存放数据的一个容器。

数组和集合的区别

(1)数组能存基本数据类型和引用类型;集合当中只能存放引用数据类型,直接放基本数据类型,也会自动帮你装箱(把基本数据类型转成对象),集合当中只能存放对象。

(2)数组长度是固定,不能再去增长;集合长度是可以改变,根据元素的增长而增加。

什么时候使用数组,什么时候使用集合类。

如果元素个数是固定,推荐使用数组;如果元素不是固定,推荐使用集合。

集合体系

这里介绍集合体系的一部分。

Collection 接口

常用方法

/* 

* 向 collection 中添加指定的元素,

* 如果添加成功返回 true,没有添加返回 false。

* 确保此 collection 包含指定的元素。

*/

boolean add(E e)

/*

* 将指定 collection 中的所有元素都添加到此 collection 中

* 如果此 collection 由于调用而发生更改,则返回 true。 否则返回 false。

*/

boolean addAll(Collection<? extends E> c)

// 移除此 collection 中的所有元素

void clear()

// 如果此 collection 包含指定的元素,则返回 true。否则返回 false。

boolean contains(Object o)

// 如果此 collection 包含指定 collection 中的所有元素,则返回 true。否则返回 false。

boolean containsAll(Collection<?> c)

/*

* 比较此 collection 与指定对象是否相等。

* 如果所定义的两个列表以相同的顺序包含相同的元素,则返回 true。

*/

boolean equals(Object o)

// 如果此 collection 不包含元素,则返回 true。

boolean isEmpty()

// 返回在此 collection 的元素上进行迭代的迭代器。

Iterator<E> iterator()

// 从此 collection 中移除指定元素的单个实例,如果存在的话,移除成功,则返回 true。

boolean remove(Object o)

/*

* 移除此 collection 中,此 collection和指定 collection的交集

* 如果此 collection 由于调用而发生更改,则返回 true

*/

boolean removeAll(Collection<?> c)

/*

* 把此 collection和指定 collection的交集赋值给调用者

* 如果此 collection 由于调用而发生更改,则返回 true

*/

boolean retainAll(Collection<?> c)

// 返回此 collection 中的元素数。

int size()

// 返回包含此 collection 中所有元素的数组

Object[] toArray()

// 返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同。

<T> T[] toArray(T[] a)

管理集合元素:

增:add(E e) 

删:remove(Object o)

改:Collection中没有定义

清空:clear()

查:

个数:size()

判包含:contains(Object o)

判空:isEmpty()

查找定位某个元素:Collection中没有定义

e.g.

public static void main(String[] args) {

Collection c = new ArrayList();

// 会自动帮你装箱(把基本数据类型转成对象)

c.add(10);

c.add(true);

}

反编译后:

public static void main(String args[])

{

Collection c = new ArrayList();

c.add(Integer.valueOf(10));

c.add(Boolean.valueOf(true));

}

e.g. Collection 遍历

public static void main(String[] args) {

Collection c = new ArrayList();

c.add(new Student("zs"));

c.add(new Student("ls"));

c.add(new Student("ww"));

// (1)转成数组,通过数组遍历

Object[] array = c.toArray(); // 自动把数组当中所有元素向上转型

for (int i = 0; i < array.length; i++) {

if (array[i] instanceof Student) { // 向下转型有风险

Student s = (Student) array[i]; // 向下转型(转回原来存放的类型)

System.out.println(s.name);

}

}

System.out.println("-----分割线------");

// (2)迭代器遍历(推荐)

Iterator it = c.iterator(); // 放到Iterator内容会自动类型提升为 Object

// 1.判断有没有元素可以迭代,如果仍有,则返回 true。

while (it.hasNext()) {

// 2. 返回游标的下一个元素,游标后移一位

Object next = it.next();

if (next instanceof Student) {

Student s = (Student) next;

System.out.println(s.name);

}

}

}

List 接口

常用方法

由 Collection 接口继承来的不再说明,见Collection 接口的常用方法

// 在列表的指定位置插入指定元素 

void add(int index, E element)

/*

* 将指定 collection 中的所有元素都插入到列表中的指定位置

* 如果此 collection 由于调用而发生更改,则返回 true。 否则返回 false。

*/

boolean addAll(int index, Collection<? extends E> c)

// 移除列表中指定位置的元素,返回从列表中移除的元素

E remove(int index)

// 返回列表中指定位置的元素

E get(int index)

// 用指定元素替换列表中指定位置的元素,返回被替换的元素

E set(int index, E element)

// 返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1

int indexOf(Object o)

// 返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回 -1

int lastIndexOf(Object o)

// 返回此列表元素的列表迭代器(按适当顺序)

ListIterator<E> listIterator()

// 返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始

ListIterator<E> listIterator(int index)

// 返回列表中指定的 [fromIndex, toIndex) 之间的部分视图。

List<E> subList(int fromIndex, int toIndex)

// 使用随附的 Comparator排序此列表来比较元素。

default void sort(Comparator<? super E> c)

管理集合元素:

增:add(E e) ;  add(int index, E element) 

删:remove(Object o) ; remove(int index)

改:set(int index, E element)

清空:clear()

排序:sort(Comparator<? super E> c)

子集合:subList(int fromIndex, int toIndex)

查:

个数:size()

判包含:contains(Object o)

判空:isEmpty()

查找定位某个元素:indexOf(Object o) ; lastIndexOf(Object o) ; get(int index)

e.g.

现在有个需求,遍历集合,如果集合中的元素等于某个值,删除这个元素。

List list = new  ArrayList();

list.add("1");

list.add("2");

list.add("3");

list.add("4");

// 遍历集合

Iterator it = list.iterator();

while(it.hasNext()) {

// 取出对应的元素

String str = (String)it.next();

// 判断该 元素是否等于 2

if(str.equals("2")) {

// 等于 2 就把2给集合当中删除

list.remove("2");

}

}

System.out.println(list);

以上代码会报 java.util.ConcurrentModificationException 并发修改异常

在迭代集合的过程当中,是不允许直接修改集合结构。

看下源码:

修改后:

List list = new  ArrayList();

list.add("1");

list.add("2");

list.add("3");

list.add("4");

Iterator it = list.iterator();

while(it.hasNext()) {

String str = (String)it.next();

if(str.equals("2")) {

it.remove(); // 删除当前正在迭代集合的元素(正在遍历的元素 next的结果)

}

}

System.out.println(list);

原理:

e.g. List特有的迭代器

现在换了一个需求,遍历集合,如果集合中的元素等于某个值,在这个元素后添加一个元素。

在迭代器中,只有remove方法,没有add方法。但是在List中有自己特有的迭代器 listIterator

private class ListItr extends Itr implements ListIterator<E>

ListItr 继承了 Itr,所以 Itr 有的方法都能用。

List list = new ArrayList();

list.add("1");

list.add("2");

list.add("3");

list.add("4");

// 在list当中有自己特有的迭代器

ListIterator it = list.listIterator();

while (it.hasNext()) {

String str = (String) it.next();

if (str.equals("2")) {

// list.add("myxq"); //会发生并发修改异常

it.add("myxq");

}

}

System.out.println(list);

ArrayList

数据结构分析

数组的大小是固定的,ArrayList 数组扩容的实现:

查询和修改比较快,通过索引就能找到对应值。

添加和删除比较慢

这也就实现了当我们不指定初始化大小的时候,添加第一个元素的时候,数组会扩容为 10.

添加和删除图示:

ArrayList 去除集合中重复的元素

public static ArrayList removeDuplicates(ArrayList list) {

// 1.创建一个空的集合

ArrayList newList = new ArrayList();

// 2.依次取出每一个元素

ListIterator it = list.listIterator();

while (it.hasNext()) {

// 3.每取出一个元素,要先判断新集合当中 ,是否已经包含了该元素

Object obj = it.next();

// 4.如果已经包含该元素,就不把该元素添加到新集合当中,不包含时才添加到新集合当中

if (!newList.contains(obj)) {

newList.add(obj);

}

}

return newList;

}

public static void main(String[] args) {

ArrayList list = new ArrayList();

list.add("a");

list.add("a");

list.add("b");

list.add("b");

list.add("c");

list.add("c");

list.add("d");

System.out.println(list);

ArrayList newList = removeDuplicates(list);

System.out.println(newList);

}

ArrayList 去除集合中重复的自定义对象元素

class Student {

String name;

int age;

Student(String name, int age) {

this.name = name;

this.age = age;

}

@Override

public String toString() {

return "Student [name=" + name + ", age=" + age + "]";

}

}

@SuppressWarnings({ "unchecked", "rawtypes" })

public class Test {

public static ArrayList removeDuplicates(ArrayList list) {

// 1.创建一个空的集合

ArrayList newList = new ArrayList();

// 2.依次取出每一个元素

ListIterator it = list.listIterator();

while (it.hasNext()) {

// 3.每取出一个元素,要先判断新集合当中 ,是否已经包含了该元素

Object obj = it.next();

// 4.如果已经包含该元素,就不把该元素添加到新集合当中,不包含时才添加到新集合当中

if (!newList.contains(obj)) {

newList.add(obj);

}

}

return newList;

}

public static void main(String[] args) {

ArrayList list = new ArrayList();

list.add(new Student("张三", 20));

list.add(new Student("张三", 20));

list.add(new Student("李四", 21));

System.out.println(list);

ArrayList newList = removeDuplicates(list);

System.out.println(newList);

}

}

以上代码发现并没有去重。

原因是 contains 是用equals(如果没有重写,默认是Object的equals,比较的是地址)判断有没有相同的元素。

修改后

class Student {

String name;

int age;

Student(String name, int age) {

this.name = name;

this.age = age;

}

@Override

public String toString() {

return "Student [name=" + name + ", age=" + age + "]";

}

@Override

public boolean equals(Object obj) {

if (this == obj)

return true;

if (obj == null)

return false;

if (getClass() != obj.getClass())

return false;

Student other = (Student) obj;

if (age != other.age)

return false;

if (name == null) {

if (other.name != null)

return false;

} else if (!name.equals(other.name))

return false;

return true;

}

}

@SuppressWarnings({ "unchecked", "rawtypes" })

public class Test {

public static ArrayList removeDuplicates(ArrayList list) {

// 1.创建一个空的集合

ArrayList newList = new ArrayList();

// 2.依次取出每一个元素

ListIterator it = list.listIterator();

while (it.hasNext()) {

// 3.每取出一个元素,要先判断新集合当中 ,是否已经包含了该元素

Object obj = it.next();

// 4.如果已经包含该元素,就不把该元素添加到新集合当中,不包含时才添加到新集合当中

if (!newList.contains(obj)) {

newList.add(obj);

}

}

return newList;

}

public static void main(String[] args) {

ArrayList list = new ArrayList();

list.add(new Student("张三", 20));

list.add(new Student("张三", 20));

list.add(new Student("李四", 21));

System.out.println(list);

ArrayList newList = removeDuplicates(list);

System.out.println(newList);

}

}

LinkedList

数据结构分析

添加和删除比较快,查询和修改比较慢。

LinkedList 特有的方法

// 将指定元素插入此列表的开头。 

void addFirst(E e)

// 将指定元素添加到此列表的结尾。

void addLast(E e)

// 获取但不移除此列表的头(第一个元素)。

E element()

// 返回此列表的第一个元素。

E getFirst()

// 返回此列表的最后一个元素。

E getLast()

// 获取并移除此列表的头(第一个元素)。

E remove()

// 移除并返回此列表的第一个元素。

E removeFirst()

// 移除并返回此列表的最后一个元素。

E removeLast()

// 将指定元素添加到此列表的末尾(最后一个元素)。

boolean offer(E e) // 类似 add(E e)

// 在此列表的开头插入指定的元素。

boolean offerFirst(E e) // 类似 addFirst(E e)

// 在此列表末尾插入指定的元素。

boolean offerLast(E e) // 类似 addLast(E e)

// 获取但不移除此列表的头(第一个元素)。

E peek() // 类似 element()

// 获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。

E peekFirst() // 类似 getFirst()

// 获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。

E peekLast() // 类似 getLast()

// 获取并移除此列表的头(第一个元素)

E poll() // 类似 remove()

// 获取并移除此列表的第一个元素;如果此列表为空,则返回 null。

E pollFirst() // 类似 removeFirst()

// 获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。

E pollLast() // 类似 removeLast()

// 从此列表中移除第一次出现的指定元素(从头部到尾部遍历列表时)。

boolean removeFirstOccurrence(Object o)

// 从此列表中移除最后一次出现的指定元素(从头部到尾部遍历列表时)。

boolean removeLastOccurrence(Object o)

// 返回以逆向顺序在此双端队列的元素上进行迭代的迭代器。元素将按从最后一个(尾部)到第一个(头部)的顺序返回。

Iterator<E> descendingIterator()

栈:先进后出

// 出栈:从此列表所表示的堆栈处弹出一个元素。

E pop() // 底层调用 removeFirst(e);

// 入栈:将元素推入此列表所表示的堆栈。

void push(E e) // 底层调用 addFirst(e);

Vector

Vector使用很少,一般都使用ArrayList 从1.2开始并到List

特有的方法

// 将指定的组件添加到此向量的末尾,将其大小增加 1。

void addElement(E obj)

// 返回此向量的组件的枚举。

Enumeration<E> elements()

e.g. 特有的遍历元素

Vector vc = new Vector();

vc.add("a");

vc.add("b");

vc.add("c");

// 获取所有元素

Enumeration e = vc.elements();

while (e.hasMoreElements()) {

System.out.println(e.nextElement());

}

与ArrayList对比

(1)都是使用数组来实现的

(2)Vector是线程安全的,内部加了锁;ArrayList当中方法没有加锁

集合的嵌套

class Student {

String name;

Student(String name) {

this.name = name;

}

}

public class Test {

public static void main(String[] args) {

/**

* 学科 学科当中是有很多班级

* 班级当中又有很多学生

*/

Student stu1 = new Student("zs1");

Student stu2 = new Student("ls1");

// 班级1

List<Student> c1 = new ArrayList<>();

c1.add(stu1);

c1.add(stu2);

Student stu3 = new Student("zs2");

Student stu4 = new Student("ls2");

// 班级2

List<Student> c2 = new ArrayList<>();

c2.add(stu3);

c2.add(stu4);

// 学科 (集合当中又存储集合)

List<List<Student>> x = new ArrayList<>();

x.add(c1);

x.add(c2);

// 把所有班级当中 的学生姓名打印出来

for (List<Student> g : x) {

// 取出每一个班级

for (Student per : g) {

System.out.println(per.name);

}

}

}

}

以上是 Java 面向对象(十一) 的全部内容, 来源链接: utcz.com/z/393739.html

回到顶部