:常见的数据结构(理解)
(1)加钱:数据结构+算法+UML+设计模式
(2)栈,队列,数组,链表
栈:先进后出
队列:先进先出
数组:查询快,增删慢
链表:查询慢,增删快
(3)面试前:百度下常见的数据结构的优缺点。
2:List的三个儿子(理解)
(1)List的三个儿子特点:(面试题)
List
|--ArrayList
底层数据结构是数组,查询快,增删慢
线程不安全,效率高
|--Vector
底层数据结构是数组,查询快,增删慢
线程安全,效率低
|--LinkedList
底层数据结构是链表,查询慢,增删快
线程不安全,效率高
(2)案例:ArrayList存储自定义对象去重复
需求:ArrayList如果存储的是学生,那么,怎么去除重复元素呢?
问题:如何知道学生是重复的?
需求:如果学生的姓名和年龄相同,我就认为是同一个学生,即重复值。
问题分析: 通过简单分析,我们估计是判断那里出问题了。
怎么办呢?
看判断的方法。
而我们又知道,判断的方法是API提供的,不是自己写的。
所以,看源码,看底层到底是怎么实现的。
通过看原码,我们发现,底层依赖的是equals()方法。
由于学生类中,我们并没有equals()方法,所以,默认用的是Object的方法。
而Object类的方法,默认比较的是地址值。
由于学生对象都是new出来的,地址值肯定不一样,所以从这个角度考虑结论是正确的。
但是不符合我们的需求。
怎么办呢?
重写equals()方法,让它按照我们的需求来比较。
代码:
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); //这里contain底层是equals方法
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());
}
}
(3):Vector的特有功能(了解内容)
A:添加功能。
void addElement( Object obj )
B:获取功能。
public Object elementAt( int index )
public Enumeration elements()
类Enumeration里边有两个方法。(类似于迭代器)
boolean hasMoreElements()
Object nextElement()
C: public int size()
JDK版本升级考虑的因素:A:安全。B:效率。C:简化书写。
(4):LinkedList的特有功能
A:添加功能
void addFirst( Object o ):将指定元素插入此列表的开头。
void addLast( Object o ):将指定元素添加到此列表的结尾。
B:获取功能
Object getFirst()
Object getLast()
C: 删除功能
Object removeFirst()
Object removeLast()
(5):面试题:用LinkedList模拟栈数据结构
这里的问题关键在于模拟栈结构就要
对外提供获取和添加功能
package cn.itcast_02;
A:第一步,自定义栈集合的类。
import java.util.LinkedList;
//自定义栈集合
public class MyStack {
//通过LinkedList模拟栈数据结构
private LinkedList list;
public MyStack()
{
list = new LinkedList();
}
public void add(Object obj)
{
list.addFirst(obj);
}
public Object get(int index)
{
return list.get(index);
}
public int size()
{
return list.size();
}
}
B:在测试类中测试。
package cn.itcast_02;
public class MyStackTest {
public static void main(String[] args) {
MyStack ms = new MyStack();
ms.add("hello");
ms.add("world");
ms.add("java");
for (int x = 0; x < ms.size(); x++) {
String s = (String) ms.get(x);
System.out.println(s);
}
}
}
(6)到底使用谁?根据需求看
是否要安全:
是:Vector
否:ArrayList,LinkedList
查询多:ArrayList
增删多:LinkedList
如果你什么都不知道,用ArrayList。
3:泛型(理解)
(1)泛型是一种把明确类型的工作放在了创建对象或者调用方法时候才去明确的特殊的类型。
(2)格式:
<数据类型>
(3)好处:(掌握)
A:解决了黄色警告线问题
B:把运行期间的转换异常给提前到了编译期间
C:优化了程序设计,不需要做强制类型转换了
1):泛型类
需求:我能不能不用重载方法,就可以实现同一个方法,输出不同类型的数据呢?
package cn.itcast_03;
//尖括号中的QQ代表的是任意类型,QQ也可以用其他任意字母代替(自定义)
public class Tool<QQ> {
//这里的QQ必须和上边尖括号中的名字一样,qq是变量名,可以自定义
public void show(QQ qq)
{
//输出QQ类型的变量qq
System.out.println(qq);
}
}
2):泛型方法
你为了保证方法传递不同的参数,你就在类上明确了类型。
这样的话,你有没有发现一个问题呢?它要是能够在调用方法的时候,
才去明确类型该有多好呢?
public class Tool
{
public <BYD> void show( BYD byd )
{
System.out.println( byd );
}
}
3):泛型接口
A:定义Inter接口的代码。
package cn.itcast_03;
public interface Inter<BMW> {
public abstract void show(BMW bmw);
}
B:接口Inter的实现类InterImpl中的代码。
package cn.itcast_03;
public class InterImpl<BMW> implements Inter<BMW> {
@Override
public void show(BMW bmw) {
System.out.println(bmw);
}
4:增强for循环(掌握)
(1)格式:
for(数组或者Collection集合的元素类型 变量 : 数组或者Collection集合的对象)
{
直接使用变量即可。
}
(2)好处:
方便了数组和Collection集合的遍历。
(3)注意(注意):
A:增强for是用来替代迭代器的。其底层就是调用的迭代器
B:不要在用增强for遍历集合的时候,用集合对集合本身进行修改。
(4)遍历List集合体系三种方式
1):迭代器
2):普通for+get list特有的功能get();
3):增强for(工作时候用)
Collection集合遍历两种方式
1):迭代器
3):增强for(工作时候用)
|