数据结构:
了解常用的数据结构:
栈、队列、堆、数据、链表、红黑树(二叉树)、图、哈希结构
栈的特点:先进后出
队列的特点:先进先出
栈和队列的示例图:
数组数据结构和链表数据结构
数组数据结构的概念和特点:
概念:存储同一种数据类型元素的容器
特点:存在引用,可以按照索引查找
优点:查询快
缺点:增删慢
链表数据结构的概念和特点:
概念:把一些节点用链子连接起来的数据结构
优点:增删快
缺点:查询慢
链表结构和数组结构的示意图
List接口的三个实现子类的特点:
A:ArrayList类的特点:
底层是数组结构,查询快,增删慢;线程不安全,效率高
B:Vector类的特点:
底层是数组机构,查询快,增删慢;线程安全,效率低
C:LinkedList类的特点:
底层是链表结构,增删快,查询慢;线程不安全,效率低
例题:
一个字符串集合ArrayList中含有如下元素:hello, world, java,
hello, java, php, android,world。要求编写程序,获得一个没有重复元素的新集合。
思路:
1 创建两个集合对象一个老集合,一个新集合
2 给老集合中添加元素
3 遍历老集合得到老集合中的每一个数据
4 再得到老集合中的数据后用新集合进行判断,判断集合中是否包含数据,
如果不包含,则把数据添加到新集合当中,如果包含不添加
代码:
public class Test1 {
public static void main(String[] args) {
// 创建一个集合,添加上面的元素
Collection c = new ArrayList();
// 创建一个新的集合
Collection c1 = new ArrayList();
// 添加元素
c.add("hello");
c.add("world");
c.add("java");
c.add("hello");
c.add(".net");
c.add("java");
c.add("php");
c.add("ios");
c.add("java");
c.add("android");
c.add("world");
System.out.println("c: " + c);
System.out.println("c1: " + c1);
// 遍历集合
// 获取迭代器
Iterator it = c.iterator();
// 遍历
while (it.hasNext()) {
String s = (String)it.next();
if(!(c1.contains(s))){
c1.add(s);
}
//System.out.println(c1.contains(it.next()));
// if(!(c1.contains(it.next()))){
// c1.add(it.next());
}
System.out.println("c1:" + c1);
}
}
结果:
例题:
ArrayList存储自定义对象去重复
代码:
import java.util.ArrayList;
import java.util.Iterator;
public class Test2 {
public static void main(String[] args) {
// 创建一个集合
ArrayList<Student> array = new ArrayList<>();
// 创建第二个集合
ArrayList<Student> array2 = new ArrayList<>();
// 创建Student对象
Student s1 = new Student("小苍", 20);
Student s2 = new Student("苍井", 20);
Student s3 = new Student("小龙", 21);
Student s4 = new Student("小龙", 21);
Student s5 = new Student("苍井", 21);
Student s6 = new Student("小泽", 18);
// 向集合array添加Student对象
array.add(s1);
array.add(s2);
array.add(s3);
array.add(s4);
array.add(s5);
array.add(s6);
// 遍历array集合
Iterator it = array.iterator();
while (it.hasNext()) {
Student s = (Student) it.next();
if (!(array2.contains(s))) {
array2.add(s);
}
}
/*
* 输出去重后的集合,由于集合arrays中存储的是Student对象的引用
* 因此,我们需要遍历每一个元素,然后输入每一个对象中对应的属性
*/
System.out.println("去重后的集合: " + array2);
for(int x=0;x<array2.size();x++){
Student s = array2.get(x);
System.out.println(s.getName() + "---" + s.getAge());
}
}
}
结果:
重点学习ArrayList
ArrayList存储字符串并遍历
代码如下:
import java.util.ArrayList;
import java.util.Iterator;
/*
* ArrayList存储字符串并遍历
*
* 作业:用ArrayList存储自定义对象并遍历。
*/
public class ArrayListDemo {
public static void main(String[] args) {
// 创建集合对象
ArrayList array = new ArrayList();
// 创建并添加元素
array.add("hello");
array.add("world");
array.add("java");
// 遍历集合
Iterator it = array.iterator();
while (it.hasNext()) {
String s = (String) it.next();
System.out.println(s);
}
System.out.println("-----------");
// for (int x = 0; x < array.size(); x++) {
// String s = (String) array.get(x);
// System.out.println(s);
// }
// 开发中,我会按照如下方式写,请问为什么?
//上面那种方式,每次都会调用size()方法,效率低。
//下面这种方式,我们只调用一次。效率较高。
int length = array.size();
for (int x = 0; x < length; x++) {
String s = (String) array.get(x);
System.out.println(s);
}
}
}
ArrayList中存储自定义对象,然后遍历
代码:
import java.util.ArrayList;
import java.util.Iterator;
/*
* ArrayList存储自定义对象并遍历
*/
public class ArrayListDemo2 {
public static void main(String[] args) {
ArrayList array = new ArrayList();
Student s1 = new Student("乔峰", 40);
Student s2 = new Student("虚竹", 36);
Student s3 = new Student("段誉", 28);
array.add(s1);
array.add(s2);
array.add(s3);
Iterator it = array.iterator();
while (it.hasNext()) {
Student s = (Student) it.next();
System.out.println(s.getName() + "***" + s.getAge());
}
System.out.println("-------------");
for (int x = 0; x < array.size(); x++) {
Student s = (Student) array.get(x);
System.out.println(s.getName() + "***" + s.getAge());
}
}
}
结果:
例题:
* ArrayList如果存储的是学生,那么,怎么去除重复元素呢?
* 问题:如何知道学生是重复的。
* 需求:如果学生的姓名和年龄相同,我就认为是同一个学生。即重复值。
*
* 通过简单分析,我们估计是判断那里出问题了。
* 怎么办呢?
* 看判断的方法。
* 而我们又知道,判断的方法是API提供的。不是自己的写的。
* 看源码,看底层到底怎么实现的。
* 通过看源码,我们发现,底层依赖的是equals()。
* 由于学生类中,我们并没有equals()方法,所以,默认用的是Object的方法。
* 而Object类的方法,默认比较的是地址值。
* 由于学生对象都是new出来的,地址值肯定不一样,所以从这个角度考虑结论是正确的。
* 但是不符合我们的需求。
* 肿么办?
* 重写equals(),让他按照我们的需要来比较。
代码如下:
public class ArrayListTest3 {
public static void main(String[] args) {
ArrayList array = new ArrayList();
Student s1 = new Student("郑成功", 40);
Student s2 = new Student("戚继光", 50);
Student s3 = new Student("戚继光", 50);
Student s4 = new Student("岳飞", 36);
Student s5 = new Student("岳飞", 40);
Student s6 = new Student("林则徐", 30);
array.add(s1);
array.add(s2);
array.add(s3);
array.add(s4);
array.add(s5);
array.add(s6);
// 创建新集合
ArrayList array2 = new ArrayList();
// 遍历旧集合,获取到每一个元素
Iterator it = array.iterator();
while (it.hasNext()) {
Student s = (Student) it.next();
// 在新集合中判断,看是否存在这个元素
if (!array2.contains(s)) {
// 如果s不再array2中存在,就添加
array2.add(s);
}
}
// array2就是没有重复元素的集合。
// 遍历array2
for (int x = 0; x < array2.size(); x++) {
Student s = (Student) array2.get(x);
System.out.println(s.getName() + "***" + s.getAge());
}
}
}
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object obj) {
// 提高效率
if (this == obj) {
return true;
}
// 提高健壮性
if (!(obj instanceof Student)) {
return false;
}
// 向下转换
Student s = (Student) obj;
return this.name.equals(s.name) && this.age == s.age;
}
}
Vector的特有功能:
* Vector的特有功能:
* A:添加功能 升级后方法
* public void addElement(Object obj) -- add(Object obj)
* B:获取功能
* public Object elementAt(int index)-- get(int index)
* public Enumeration elements()-- Iterator
* boolean hasMoreElements()-- hasNext()
* Object nextElement()-- next()
* C:长度功能
* public int size()
*
* JDK版本升级:
* A:安全
* B:效率
* C:简化书写
Vector类特有方法代码;
public class VectorDemo {
public static void main(String[] args) {
// 创建集合对象
Vector v = new Vector();
// 添加元素
v.addElement("hello");
v.addElement("world");
v.addElement("java");
// 遍历
// System.out.println(v.elementAt(0));
// System.out.println(v.elementAt(1));
// System.out.println(v.elementAt(2));
for (int x = 0; x < v.size(); x++) {
String s = (String) v.elementAt(x);
System.out.println(s);
}
System.out.println("----------------");
//public Enumeration elements()
Enumeration en = v.elements();
while(en.hasMoreElements()){
String s = (String)en.nextElement();
System.out.println(s);
}
}
}
结果
LinkedList的特有方法:
A:添加功能
* void addFirst(Object e)
* void addLast(Object e)
* B:获取功能
* Object getFirst()
* Object getLast()
* C:删除功能
* Object removeFirst()
* Object removeLast()
代码:
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList link = new LinkedList();
link.add("hello");
link.add("world");
link.add("java");
// 添加功能
// link.addFirst("EE");
// link.addLast("ME");
// 获取功能
// System.out.println("getFirst:"+link.getFirst());
// System.out.println("getLast:"+link.getLast());
// 删除功能
System.out.println("removeFirst:" + link.removeFirst());
System.out.println("removeLast:" + link.removeLast());
System.out.println("link:" + link);
}
}
结果:
分析结果可知,LinkedList方法中的remove功能,影响结合中的元素
面试题:
通过LinkedList模拟栈数据结构
要模拟的内容的特点:
先进后出。
通过LinkedList模拟栈数据结构: 它的意思是说,你有一个LinkedList可以用,但是,你需要自己定义一个栈集合。
对外提供获取和添加功能。
实现栈结构代码:
import java.util.LinkedList;
/*
* 自定义栈集合。
*/
public class MyStack {
private LinkedList link;
public MyStack() {
link = new LinkedList();
}
public void add(Object obj) {
link.addFirst(obj);
}
public Object get(int index) {
return link.get(index);
}
public int size() {
return link.size();
}
}
使用自定义栈结构代码;
public class LinkedListTest {
public static void main(String[] args) {
// 创建集合对象
MyStack ms = new MyStack();
// 创建并添加元素
ms.add("hello");
ms.add("world");
ms.add("java");
// 获取
// System.out.println(ms.get(0));
// System.out.println(ms.get(1));
// System.out.println(ms.get(2));
// System.out.println(ms.get(3));
for (int x = 0; x < ms.size(); x++) {
String s = (String) ms.get(x);
System.out.println(s);
}
}
}
结果:
分析结果:实现了栈的特点:先进后出
泛型:
ClassCastException:类型转换问题
泛型:任意的类型。是一种把明确数据类型的工作放在了创建对象或者调用方法 时候进行的特殊的类型。
泛型的格式:
<数据类型>
为什么会有泛型? 就是为了解决黄线和类型转换问题。
怎么解决呢?
就是模仿数组解决的,在定义集合的时候,告诉集合,你只能存储什么类型的元 素。
怎么告诉呢,通过泛型。
泛型的好处:
A:解决黄色警告线问题。
B:把运行期间的类型转换异常提前到了编译期间。
C:优化程序设计。
泛型在哪些地方用啊?
别问我,问API。如果类或者接口后面有<>,那么这就是泛型的体现。它就是要你在使用的时候明确类型的。
泛型一般就在集合中用。
代码:
<span style="font-size:24px;">public class ArrayListDemo {
public static void main(String[] args) {
// 用ArrayList存储字符串并遍历
ArrayList<String> array = new ArrayList<String>();
array.add("hello");
array.add("world");
array.add("java");
// array.add(10);// 等价于array.add(new Integer(10));
Iterator<String> it = array.iterator();
while (it.hasNext()) {
String s = (String) it.next();
System.out.println(s);
// System.out.println(it.next());
}
// 数组在定义的时候,就明确告诉你了,我们的元素是某种固定的类型。不能是其他类型。
// String[] strArray = new String[3];
// strArray[0] = "hello";
// strArray[1] = "world";
// strArray[2] = 0;
}
}
</span>
增强for循环
* 格式:
* for(数组或者Collection集合中元素类型 变量名 : 数组或者Collection 集合对象)
* {
* 使用变量名即可。
* }
*
* 作用:简化数组和Collection集合的变量。
* 注意:增强for是用来替代迭代器的。不能再用增强for的时候,用集合对象对集合进行改变。
代码:
public class ForDemo {
public static void main(String[] args) {
// 整型数组
int[] arr = { 1, 2, 3, 4, 5 };
// 普通for
for (int x = 0; x < arr.length; x++) {
System.out.println(arr[x]);
}
System.out.println("--------------");
// 增强for
for (int x : arr) {
System.out.println(x);
}
System.out.println("--------------");
// 字符串数组
String[] strArray = { "hello", "world", "java" };
// 增强for
for (String str : strArray) {
System.out.println(str);
}
System.out.println("--------------");
// 集合
ArrayList<String> array = new ArrayList<String>();
array.add("hello");
array.add("world");
array.add("java");
for (String str : array) {
System.out.println(str);
}
System.out.println("--------------");
// 增强for和迭代器我们一般只选一种。
// 增强for是来替代迭代器的。
// ArrayList<String> array2 = new ArrayList<String>();
// array2.add("hello");
// array2.add("world");
// array2.add("java");
// ConcurrentModificationException
ArrayList<String> array2 = null;
// NullPointerException
for (String str : array2) {
if (str.equals("world")) {
array2.add("EE");
}
}
}
}
结果