一.LinkedList
package com.example.demo;
import java.util.*;
/**
* 迭代器中有next方法和remove方法.需要注意的是remove方法移除的是next所返回的.
* remove方法和next方法永远是同步使用的.
*
* LinkedList 和 ArrayList相比 仅仅是在头和尾上多了2个方法.
*
* 扩展:
* 动态代理
*
* Created by howell on 2016/8/13 0013.
*/
public class Test {
/**
*
* 栈:先进后出
* 队列: 先进先出
*
*
* 使用循环数组模拟栈和队列
* 使用链表模拟栈和队列.
* @param args
*/
public static void main(String[] args) {
//--LinkedList 链表源自于C语言中链表.
/*
C语言中使用结构体来存储数据.结构体中有2个区域分别是数据区和指针区
数据区记录数据
指针区记录上一个节点和下一个节点的地址.
LinkedList是有序的.且在内存中是非连续的(这里是区别于ArrayList)
*/
List<String> arrayList = new ArrayList<>();
arrayList.add("A");
arrayList.add("B");
arrayList.add("C");
long startTime = System.currentTimeMillis();
for (String str : arrayList) {
System.out.println(str);
}
long endTime = System.currentTimeMillis();
System.out.println("arrayList:\t" + (endTime - startTime));
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("A");
linkedList.add("B");
linkedList.add("D");
linkedList.set(2,"C");
long i = System.currentTimeMillis();
for (String str :linkedList) {
System.out.println(str
);
}
long j = System.currentTimeMillis();
linkedList.addFirst("D");
linkedList.addLast("E");
System.out.println("-------------------------");
for (String str :linkedList)
System.out.println(str);
/**
*
*练习: 使用链表模拟栈
* 思考流程:
* 1.栈是一种数据结构,还有其他数据结构.不同的数据结构都有存和取2个方法
* 因此第一步是抽取接口
*
* 存
* 取
* 获取大小
* 查找
* 2.为了扩展方便模仿Java的集合框架提供抽象类.
*
* 3.提供具体的实现类.并重写压栈和出栈的方法
*
*/
System.out.println("linkedList:\t"+(j - i));
}
}
模拟栈的压栈入栈练习,为了熟练oop的思想过程
第一步,抽取接口
/**
* 常见的命名方式 如果是接口可以选择使用大写的I开头.
* Created by Jun on 2016/8/13 0013.
*/
public interface IStack<E>{
/**
* 添加一个元素
* @param e 要被添加的元素
* @return true 添加成功.其它情况false
*/
public boolean add(E e);
/**
* 取元素
* @return 最后一个元素
*/
public E getElement();
/**
* 返回栈内的元素个数
* @return
*/
public int size();
}
第二步,抽象类,用于拓展
/**
*
* 为了扩展需要.
*
*
*
* Created by Jun on 2016/8/13 0013.
*/
public abstract class AbstractStack<E> implements IStack<E>{
}
第三部,实现类,运行
package com.example.demo.ex;
import java.util.LinkedList;
import java.util.List;
/**
* Created by Jun on 2016/8/13 0013.
*/
public class MyStack<E> extends AbstractStack<E>{
//--添加存储数据的
LinkedList<E> mLinkedList;
List<E> mList;
/**
* 利用无参构造完成mLinkedList的初始化操作
*/
public MyStack() {
mLinkedList = new LinkedList<E>();
}
/**
* 如果使用这种动态的使用集合时,下面就不可以使用addLast()等方法要使用List中的方法
* @param mList
*/
public MyStack(List<E> mList) {
this.mList = mList;
}
//--因为LinkedList允许添加null作为元素.可以选择添加验证也可以不添加验证
@Override
public boolean add(E e) {
// if (e == null)
// return false;
// mLinkedList.add(null);
return mLinkedList.add(e);
}
/**
* 考虑从栈中取出时是移除.选择使用remove方法
* 思考:从一个集合中删除数据是选择使用remove还是选择使用迭代器的remove方法.
* @return
*/
@Override
public E getElement() {
return mLinkedList.removeLast();
}
@Override
public int size() {
return mLinkedList.size();
}
}
package com.example.demo.ex;
import java.util.AbstractList;
import java.util.Collection;
import java.util.LinkedList;
/**
* Created by Jun on 2016/8/13 0013.
*/
public class Test {
public static void main(String[] args) {
//--选择以接口为类型,创建不同的儿子类实例对象.符合多态.符合OO中的面向抽象不要面向实现
//--当决定选择使用集合时不需要考虑具体的实现方式..只有当需要一个明确的对象时才考虑使用哪一个数据结构.
//--并且这样做的好处便于扩展.如果IStack有n个实现类.只有类在加载时才
//--知道要创建的是哪一个对象.
IStack stack = new MyStack<>();
stack.add("A");
stack.add("B");
stack.add("C");
//for (String str : stack)//-foreach 只能用于实现了Iterator接口的
System.out.println(stack.size() + "\t:size");
int size = stack.size();
/*for (int i = 0 ;i < 3 ;i ++){
System.out.println(stack.getElement());
}*/
while(stack.size() != 0){
System.out.println(stack.getElement());
}
}
}
二 Map
package com.example.demo.MapDemo;
import java.util.*;
/**
*
* Map 是一种很特殊的数据结构 基于key-value 来存储数据.
* key-value 映射.只允许一一映射.且key具有唯一性,不可以出现重复的.
* Map中有2个常用类
* HashMap:底层使用的是散列算法.当一个键值对添加到HashMap中时会首先经过散列算法进行转换把key转换程对应的数字.
* 按照该数字的顺序进行存放,因此HashMap存入的顺序和取出的顺序不一定一致的.
* TreeMap
* 比较已学的集合
*
* 是否有序 是否允许重复元素
* Collection 否 是
*
* List 是 是
*
* Set
* HashSet 否 否
* TreeSet 有(二叉树) 否
*
* Map
* HashMap 否 key不允许重复,value可以重复
* TreeMap 有(二叉树) key不允许重复,value可以重复
* Created by Jun on 2016/8/13 0013.
*/
public class Test {
public static void main(String[] args) {
//--key/value extend Object 上限.. 因Object定义了一个基调 只能是引用类型
Map<Integer,Double> map = new Map<Integer, Double>() {
@Override
public int size() {
return 0;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public boolean containsKey(Object key) {
return false;
}
@Override
public boolean containsValue(Object value) {
return false;
}
@Override
public Double get(Object key) {
return null;
}
@Override
public Double put(Integer key, Double value) {
return null;
}
@Override
public Double remove(Object key) {
return null;
}
@Override
public void putAll(Map<? extends Integer, ? extends Double> m) {
}
@Override
public void clear() {
}
//--返回当前Map中所有key的集合
@Override
public Set<Integer> keySet() {
return null;
}
// 保存Map中所有value的集合
@Override
public Collection<Double> values() {
return null;
}
//--获取Map中所有的键值对.
@Override
public Set<Entry<Integer, Double>> entrySet() {
return null;
}
};
//--isNaN 是浮点数(float,double)的一个特殊方法用于判断一个元素是否是一个数字
Map<String,Integer> mapTwo = new HashMap<>();
//--NaN 是Not A Number 的缩写.浮点数还有2个特殊值.无穷大和无穷小.
//Double.isNaN(0.1);
for (int i = 0 ;i < 10 ;i++){
//String.valueOf 把一个基本类型转换为String
//--可以直接写i 所以因为jdk1.5之后自动装箱
mapTwo.put("Key"+String.valueOf(i),i);
}
for (int i = 0 ;i < mapTwo.size();i ++){
System.out.println(mapTwo.get("Key"+String.valueOf(i)));
}
System.out.println("------------------获取所有的Key");
Set<String> keys = mapTwo.keySet();
for (String key :keys) {
System.out.println(key);
}
System.out.println("------------------获取所有的Values");
//--返回值类型是一个Collection.我们提供谁的引用来指向
Collection<Integer> collection = mapTwo.values();
Iterator<Integer> iterator = collection.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("------------------获取所有的键值对");
Set<Map.Entry<String,Integer>> values = mapTwo.entrySet();//values中包含了所有的键值对
Iterator iterator1 = values.iterator();
while(iterator1.hasNext()){
System.out.println(iterator1.next());
}
}
}