大数据预科班14
复习
1. 顶级父类Throwable:Error,Exception
2. Exception:编译时异常、运行时异常
3. 自定义异常
4. 异常的捕获和处理--多catch;同一父类;分组。
5. finally控制语句(return,throw,break,continue)之前
集合
- 顶级集合Collection:容器、大小不定--泛型
- List
1. 有序
2. 可重复
1. 基于数组
2. 默认容量为10,每次扩容上一次的一半;内存空间连续
3. 增删元素较慢--移动元素
4. 查询较快--下标
5. 线程不安全
6. 展示--查询居多时
Vector
- 基于数组
- 初始大小:10
- 扩容:每次扩容一倍,内存空间连续
- 增删较慢,查询较快
- 线程安全
- java的最早的集合
- 原生elementAt==get等
- elements返回值为Enumeration,本质为迭代器
Enumeration<String> en=v.elements();
//判断后续是否还有元素
while(en.hasMoreElements){
//挪动指针指向下一个元素
String s=en.nextElement();
System.out.print(s);
}
- 注:迭代删除时--跳跃删除(指针移动的同时,数组也移动)
Stack
- 栈:先进后出
- 将元素放入栈中:压栈/入栈
- 将元素取出:弹栈/出栈
- 最先放入栈中的元素--栈底元素
- 最后放入栈中的元素--栈顶元素
- 基于数组(继承Vector)
- 方法
1. 入栈--push(存正常存【打印时按存的顺序】,取倒着取)
2. 出栈--pop(取出并弹出)
3. 获取栈顶元素并不移除--peek
4. 判断栈空empty
5. search(o)返回元素在栈中出现的位置--栈顶向栈底查找(基数为1)
练习
package com.peng.demo;
import java.util.EmptyStackException;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Testq {
public static void main(String[] args) {
Testq t = new Testq();
t.push("a");
t.push("b");
t.push("c");
t.push("d");
System.out.println(t.pop());
System.out.println(t);
}
// 用Vector实现Stack
Vector<String> v = new Vector<String>();
boolean empty() {
if (v.isEmpty()) {
return true;
} else {
return false;
}
}
String peek() {
if (v.size() <= 0) {
throw new EmptyStackException();
}
return v.get(v.size() - 1);
}
String pop() {
if (v.size() <= 0) {
throw new EmptyStackException();
}
String temp = v.get(v.size() - 1);
v.remove(v.size() - 1);
return temp;
}
String push(String s) {
v.add(s);
return s;
}
int search(String s) {
return v.size() - v.indexOf(s);
}
public String toString() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < v.size(); i++) {
sb.append(v.get(i) + ",");
}
return sb.toString().substring(0, sb.toString().length() - 1);
}
}
package com.peng.demo;
import java.util.Arrays;
import java.util.EmptyStackException;
/*
* 数组实现Stack
*/
public class Test3 {
String[] arr = new String[10];
int size = 0;
String pop() {
// 判空
if (size <= 0) {
throw new EmptyStackException();
} else {
String temp = arr[size - 1];
size--;
return temp;
}
}
String peek() {
// 判空
if (size <= 0) {
throw new EmptyStackException();
} else {
String temp = arr[size - 1];
return temp;
}
}
void push(String s) {
// 判断是否需要扩容
if (size >= arr.length) {
// 扩容
arr = Arrays.copyOf(arr, arr.length * 2);
}
arr[size] = s;
size++;
}
int search(String s) {
for (int i = 0; i < size; i++) {
if (arr[i] == s || s != null && arr[i].equals(s)) {
return size - 1 - i + 1;
}
}
return -1;
}
boolean empty() {
if (size == 0) {
return true;
} else {
return false;
}
}
public static void main(String[] args) {
Test3 t = new Test3();
t.push("a");
t.push("b");
t.push("c");
System.out.println(t.pop());
System.out.println(t.peek());
System.err.println(t.size);
}
}
LinkedList
- 基于链表
- 内存空间不连续
- 增删元素较快
- 查询较慢
- 线程不安全
- 购物车--增删频繁
1. 节点->节点对象->节点类(Node)
2. 属性:上一个节点(Node);存储数据(String);下一个节点(Node);
3. 方法:允许获取和设置数据getter/setter
4. 头结点、尾节点、节点个数
练习
package com.peng.demo;
/*
* 操作节点的类
*/
public class LinkedListDemo {
private Node first;// 头结点
private Node last;// 尾结点
private int size;// 结点个数
// 构造函数
public LinkedListDemo() {
}
// 添加节点方法
public void add(String s) {
// 如果头结点为空,则指向头结点
if (first == null) {
this.first = new Node(null, s, null);
// 因为只有一个结点,所以尾节点指向头结点,表示同一个
this.last = this.first;
} else {
// 如果不是头结点,新节点指向原来的尾节点
Node node = new Node(this.last, s, null);
this.last.next = node;
this.last = node;
}
size++;
}
// 指定位置添加新的节点
public void add(int index, String s) {
// 判断下标越界
if (index > size) {
throw new IndexOutOfBoundsException("Index:" + index + ",Size:"
+ size);
} else if (0 == index) {
// 插到头结点
Node node = new Node(null, s, this.first);
this.first.prev = node;
this.first = node;
size++;
} else if (index == size) {
// 插到末尾
this.add(s);
} else {
// 插到中间位置
Node temp = this.first;
for (int i = 0; i <= index - 1; i++) {
// 目标位置上的节点
temp = temp.next;
}
// 目标位置的上一个节点
Node prev = temp.prev;
// 要插入的节点
Node insertNode = new Node(prev, s, temp);
// 将目标位置的上一个节点变成当前节点
prev.next = insertNode;
// 将该位置的原先节点的上一位换为要插入的节点
temp.prev = insertNode;
size++;
}
}
// 移除节点方法
public void remove(int index) {
// 判断下标越界
if (index >= size) {
throw new IndexOutOfBoundsException("Index:" + index + ",Size:"
+ size);
}
if (index == 0) {
this.first = this.first.next;
this.first.prev = null;
} else if (index == size - 1) {
this.last = this.last.prev;
this.last.next = null;
} else {
// 记录要找的节点
Node node = this.first;
for (int i = 0; i < index; i++) {
node = node.next;
}
// 获取上一个节点和下一个节点
Node prev = node.prev;
Node next = node.next;
// 把上一节点的下一位改为下一个节点
prev.next = next;
// 把下一节点的上一位=改为上一个节点
next.prev = prev;
}
size--;
}
// 获取节点下标的方法
public int indexOf(String s) {
Node node = this.first;
for (int i = 0; i < size; i++) {
if (node.data == s || s != null && s.equals(node.data)) {
return i;
}
node = node.next;
}
return -1;
}
// 打印方法
public String toString() {
StringBuilder sb = new StringBuilder("[");
Node node = this.first;
for (int i = 0; i < size; i++) {
sb.append(node.data).append(", ");
node = node.next;
}
String str = sb.toString();
if (str.length() > 1) {
str = str.substring(0, str.length() - 2);
}
return str + "]";
}
// ---------------------内部类----------------------------
private class Node {
Node prev;// 上一个节点
String data;// 数据
Node next;// 下一个节点
// 构造函数
public Node(Node prev, String data, Node next) {
super();
this.prev = prev;
this.data = data;
this.next = next;
}
// 获取数据值
public String getData() {
return data;
}
// 更改数据值
public void setData(String data) {
this.data = data;
}
}
// ---------------------内部类----------------------------
public static void main(String[] args) {
LinkedListDemo l = new LinkedListDemo();
l.add("0");
l.add("1");
l.add("2");
l.add(0, "22");
l.add(4, "33");
System.out.println(l.indexOf("22"));
System.out.println(l.indexOf("33"));
System.out.println(l);
}
}
Set
HashSet
- 添加元素,不保证元素的顺序;底层依据元素的hashCode来存储【桶【1,2,3,4,5....哈希码的开头】】
- 相同元素:直接舍弃
验证:a
验证思路:利用String的常量池和构造函数(new String(""))的地址的不同的特性
dd("a");
dd(new String("a"));
for(String s:set){
if("a".equals(s)){
System.out.println("直接舍弃");
}else{
System.out.println("覆盖");
}
}
- 默认初始容量16,加载因子0.75f--警戒线,扩容(第13位),每次扩容一倍16,32,64...
- 默认和加载因子都可以认为初始化
- equals--只要元素一致就为true,不关心元素的存储顺序
- 线程不安全的集合
Queue队列
- 先进先出
- 先放进去的元素:对头元素
- 最后放入的元素:队尾元素
- 方法
1. add--offer
2. element(获取对头元素但不移除,获取失败报错NoSuchElementException)--peek(获取对头元素但不移除,获取失败返回null)
3. poll--remove
| 抛出异常 | 返回特殊值 |
---|
插入 | add(e) | offer()e |
移除 | remove | poll |
检查 | element | peek |
线性集合--有序、线性的。List,Queue
Collections
- Collections的工具类
- 方法
- Comparator比较器(Collectios.sort(list,new Comparator(compare(){})));
1. 反转列表reverse
2. Collectios.sort(list,new Comparator(compare(){}))
返回值为正数:s1>s2 交换
返回值为负数:s1<s2 不交换
如果没有指定规则,底层自动调用compareTo方法进行排序,元素对应的类必须实现Comparable接口,重写compareTo方法
疯狂值
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
public class CrazyExer1 {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
// 获取输入的数字个数
int number = s.nextInt();
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < number; i++) {
list.add(s.nextInt());
}
s.close();
// 需要对集合进行排序
Collections.sort(list);
int sum1 = sort(list);
Collections.reverse(list);
int sum2 = sort(list);
System.out.println(sum1 > sum2 ? sum1 : sum2 );
// 5 10 15 20 50 70 80
}
public static int sort(List<Integer> list) {
// 存储排序之后的结果
List<Integer> result = new ArrayList<Integer>();
// 先放入集合的最后一位
result.add(list.get(list.size() - 1));
// 标记存放的情况
// 0->前小
// 1->后小
// 2->前大
// 3->后大
int i = 0;
for (int start = 0, end = list.size() - 2; start <= end;) {
if (i == 0) {
result.add(0, list.get(start));
start++;
} else if (i == 1) {
result.add(list.get(start));
start++;
} else if (i == 2) {
result.add(0, list.get(end));
end--;
} else {
result.add(list.get(end));
end--;
i = -1;
}
i++;
}
// 记录和
int sum = 0;
for (int j = 0; j < result.size() - 1; j++) {
sum += Math.abs(result.get(j) - result.get(j + 1));
}
return sum;
}
}
import java.util.Arrays;
import java.util.Scanner;
public class CrazyExer2 {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int number = s.nextInt();
int[] arr = new int[number];
for (int i = 0; i < number; i++) {
arr[i] = s.nextInt();
}
s.close();
// 数组排序
Arrays.sort(arr);
int sum1 = sort(arr);
for (int start = 0, end = arr.length - 1; start < end; start++, end--) {
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}
int sum2 = sort(arr);
System.out.println(sum1 > sum2 ? sum1 : sum2);
}
private static int sort(int[] arr) {
int[] result = new int[arr.length];
int mid = arr.length / 2;
result[mid] = arr[arr.length - 1];
int i = 0;
int offset = 1;
for (int start = 0, end = arr.length - 2; start <= end;) {
if (i == 0) {
result[mid - offset] = arr[start];
start++;
} else if (i == 1) {
result[mid + offset] = arr[start];
start++;
offset++;
} else if (i == 2) {
result[mid - offset] = arr[end];
end--;
} else {
result[mid + offset] = arr[end];
end--;
offset++;
i = -1;
}
i++;
}
int sum = 0;
for (int j = 0; j < result.length - 1; j++) {
sum += Math.abs(result[j] - result[j + 1]);
}
return sum;
}
}