Java-013-泛型和集合

泛型

先看代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Demo01泛型 {
// 泛型
// 定义了hash表 key是 String类型 value是 Integer类型
static HashMap<String,Integer> counts = new HashMap<>();

static Stack<String> stringStack = new Stack<>();

static Stack<Integer> intStack = new Stack<>();


public static void main(String[] args) {
stringStack.push("abc");

String one = stringStack.pop();

intStack.push(1);
Integer two = intStack.pop();

// intStack.push("ssss"); 规定了Stack 内的类型是 int的 所以无法 加入 String类型的
}
}

为什么有泛型?

假如我们想要实现一个只接受 Integer 和一个只接受String 的栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class IntStack {
ArrayList<Integer> store = new ArrayList<>();

public void push(Integer item){
store.add(item);
}

public Integer pop(){
Integer tmp = store.get(store.size() - 1);
store.remove(store.size() - 1);
return tmp;
}

public int size(){
return store.size();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class StringStack {
ArrayList<String> store = new ArrayList<>();

public void push(String item){
store.add(item);
}

public String pop(){
String tmp = store.get(store.size() - 1);
store.remove(store.size() - 1);
return tmp;
}

public int size(){
return store.size();
}
}

很明显,代码结构和意思都一样,很重复,但是有了问题就是bug,改两次

泛型出现了!

泛型出现了!

泛型出现了!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 自己实现一个泛型,支持任意类型的Stack ,
// 把数据类型变成参数,把重复代码去除了 如 IntStack / StringStack
// T 是 类型参数
public class Stack2<T> {
ArrayList<T> store = new ArrayList<>();

public void push(T item){
store.add(item);
}

public T pop(){
T tmp = store.get(store.size() - 1);
store.remove(store.size() - 1);
return tmp;
}

public int size(){
return store.size();
}
}

集合 List

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 列表
List<String> arrayList = new ArrayList<>();
List<String> linkedList = new LinkedList<>();

// 操作 在尾部添加
arrayList.add("hello");
arrayList.add("world");
arrayList.add("~~~~");

// 通过索引去访问
arrayList.get(0);

//arrayList.subList(0,5); // 取出 索引从 0 到 5 位置的列表 内容不够就报错

// 通过索引 删除
arrayList.remove(0);

// 访问 列表的长度
int size = arrayList.size();

// for循环里的语法糖

for (String item: arrayList) {
System.out.println( item );
}

Set

1
2
3
4
5
6
7
8
9
10
11
12
// Set 主要用来去重复
Set<String> set = new HashSet<>();

set.add("a");
set.add("b");
set.add("c");

set.add("a"); // 去重复

for (String item: set) {
System.out.println( item );
}

练习题

汉诺塔问题

1
2
3
4
5
6
7
8
9
在经典的汉诺塔问题中,有 3 个塔和 N 个可用来堆砌成塔的不同大小的盘子。要求盘子必须按照从小到大的顺序从上往下堆 (如,任意一个盘子,其必须堆在比它大的盘子上面)。同时,你必须满足以下限制条件:

(1) 每次只能移动一个盘子。
(2) 每个盘子从堆的顶部被移动后,只能置放于下一个堆中。
(3) 每个盘子只能放在比它大的盘子上面。

请写一段程序,实现将第一个堆的盘子移动到最后一个堆中.

在编程训练网站完成训练: https://www.lintcode.com/problem/mock-hanoi-tower-by-stacks/description

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class Tower {
private Stack<Integer> disks;

public Tower(int i) {
// create three towers
disks = new Stack();
}
public void add(int d) {
// Add a disk into this tower
if (!disks.isEmpty() && disks.peek() <= d) {
System.out.println("Error placing disk " + d);
} else {
disks.push(d);
}
}
public void moveTopTo(Tower t) {
// Move the top disk of this tower to the top of t.
if(t.disks.isEmpty() || (!disks.isEmpty() && t.disks.peek() >= disks.peek())) {
t.disks.push(disks.pop());
}
}
public void moveDisks(int n, Tower destination, Tower buffer) {
// Move n Disks from this tower to destination by buffer tower
if(n <= 0) {
return;
} else if(n == 1) {
moveTopTo(destination);
} else {
moveDisks(n-1, buffer, destination);
moveDisks(1, destination, buffer);
buffer.moveDisks(n-1, destination, this);
}
}
public Stack<Integer> getDisks() {
// write your code here
return disks;
}
}

找不同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Given two strings s and t which consist of only lowercase letters.

String t is generated by random shuffling string s and then add one more letter at a random position.

Find the letter that was added in t.

输入给两个只包含小写字母的字符串 S 和 T.

字符串 T 是在字符串 S 基础上添加一个小写字母, 然后随机打乱之后生成.

请找出那个被加入的小写字母.

示例:

Input:
s = "abcd"
t = "abcde"

Output:
e

Explanation:
'e' is the letter that was added.
在线测试网站: https://leetcode.com/problems/find-the-difference/description

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package work;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

public class Test02 {

public static void main(String[] args) {
char a = findTheDifference("abc","abcd");
System.out.println(a);
}


public static char findTheDifference(String s, String t) {
HashMap<Character,Integer> hash = new HashMap<>();

String tmp = s + t;
for(int i = 0;i<tmp.length();i++){
char current = tmp.charAt(i);
if(hash.containsKey(current)){
hash.put(current,hash.get(current) + 1);
}else{
hash.put(current,1);
}
}

Set<Character> a = hash.keySet();
Character res = null;
for (Character item: a) {
if(hash.get(item)==1){
res = item;
break;
}
}
return res;
}
}

Min Stack

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.

push(x) -- Push element x onto stack.
pop() -- Removes the element on top of the stack.
top() -- Get the top element.
getMin() -- Retrieve the minimum element in the stack.
设计一个栈, 支持4种操作: push, pop, top和getMin, 关键是getMin是获取栈中的最小值.

示例:

MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> Returns -3.
minStack.pop();
minStack.top(); --> Returns 0.
minStack.getMin(); --> Returns -2.
基本代码框架:

class MinStack {

/** initialize your data structure here. */
public MinStack() {

}

public void push(int x) {

}

public void pop() {

}

public int top() {

}

public int getMin() {

}
}

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package work;

import java.util.ArrayList;

class MinStack {
private ArrayList<Integer> store;
/** initialize your data structure here. */
public MinStack() {
store = new ArrayList<>();
}

public void push(int x) {
store.add(x);
}

public void pop() {
if(store.size()==0){
throw new Error("数组元素为空");
}
store.remove(store.get(store.size()-1));
}

public int top() {
if(store.size()==0){
throw new Error("数组元素为空");
}
return store.get(store.size()-1);
}

public int getMin() {
if(store.size()==0){
throw new Error("数组元素为空");
}

int res = store.get(0);
for (int i = 1; i < store.size(); i++) {
if( res > store.get(i) ){
res = store.get(i);
}
}
return res;
}
}

推荐一个 idea的插件

1
2
3
4
5
首选项- plugins-搜索 rainbow brackets 彩虹括号

bytecode viewer 字节码查看器
Key Promoter X 快捷键提示插件
Stream java8流调试器,debug 的bar里最后一个按钮

推荐书籍

  • Efective java
  • 设计模式
  • 算法**(强烈推荐)
  • if web开发 推荐
    • Spring
    • Play
  • 分布式系统开发
    • Hadoop
    • MapReduce