20172302 《Java軟件結構與數據結構》第四周學習總結
2018年學習總結博客總目錄:第一周 第二周 第三周 第四周
教材學習內容總結
第六章 列表
1.列表是對象的有序集合,在 List 界面中定義。 List 接口表示集合框架中的列表。列表可以具有重復的元素。並且我們可以在列表中存儲多個空值。
2.列表集合 是一種概念性的表示方法,其思想是使事物以線性列表的方式進行組織,就像棧和隊列一樣,列表也可以使用數組和鏈表來實現。列表集合沒有內在的容量大小,它可以隨著需要而增大。列表集合更一般化,可以在列表的中間和末端添加和刪除元素。
3.列表可以分為有序列表、無序列表、索引列表。
- 有序列表,是基於列表中元素的某種特性的。列表基於某個關鍵值排序,對於已經添加到有序列表中的元素,只要給定了元素的關鍵值,同時列表已經定義了元素的所有關鍵值,那麽它在列表中就有一個固定的位置。
- 無序列表,各個元素的位置並不基於元素的任何內在特性,但是不要被名字誤導, 無序列表中的元素是按照特殊順序放置,只是這種順序與元素本身無關,列表的使用者會決定列表的順序。
- 索引列表,與無序列表類似,索引列表的各個元素之間也不存在能夠決定他們在列表中順序的內在關系。列表的使用者決定了元素的順序,不過,除此之外,其每個元素都能夠從一個數字索引值得到引用,該索引值從列表的頭開始從0連續增加直到列表末端。當列表發生改變,索引值就響應的調整以保持順序和連續性。索引列表為他的元素維護一段連續的數字索引值。
4.列表的總體UML圖
5.Java集合API中的列表所定義的一些基本操作,見下表
操作 | 描述 |
---|---|
add | 向列表末端添加一個元素 |
add(int index, E element) | 在列表的指定位置插入指定元素 |
get(int index) | 返回列表中指定位置的元素 |
remove(int index) | 移除列表中指定位置的元素 |
remove(Object o) | 從此列表中移除第一次出現的指定元素(如果存在) |
set(int index, E element) | 用指定元素替換列表中指定位置的元素 |
size() | 返回列表中的元素數 |
6.①無序列表的使用:學習計劃;②索引列表的使用:Josephus問題。
7.列表ADT
(1)列表的常見操作
操作 | 描述 |
---|---|
removeFirst | 從列表中刪除第一個元素 |
removeLast | 從列表中刪除最後一個元素 |
remove | 從列表中刪除某個元素 |
first | 查看位於列表前端的元素 |
last | 查看位於列表末端的元素 |
isEmpty | 確定列表是否為空 |
size | 確定列表中的元素數 |
(2)接口ListADT的代碼
import java.util.Iterator;
public interface ListADT<T> extends Iterable<T>
{
public T removeFirst();
public T removeLast();
public T remove(T element);
public T first();
public T last();
public boolean contains(T target);
public boolean isEmpty();
public int size();
public Iterator<T> iterator();
public String toString();
}
(3)有序列表接口類代碼
public interface OrderedListADT<T> extends ListADT<T>
{
public void add(T element);
}
(4)無序列表接口類代碼
public interface UnorderedListADT<T> extends ListADT<T>
{
public void addToFront(T element);
public void addToRear(T element);
public void addAfter(T element, T target);
}
8.使用數組實現列表
- ArrayList類的頭和類級代碼:
public abstract class ArrayList<T> implements ListADT<T>, Iterable<T>
{
private final static int DEFAULT_CAPACITY = 100;
private final static int NOT_FOUND = -1;
protected int rear;
protected T[] list;
protected int modCount;
public ArrayList()
{
this(DEFAULT_CAPACITY);
}
public ArrayList(int initialCapacity)
{
rear = 0;
list = (T[])(new Object[initialCapacity]);
modCount = 0;
}
}
- remove操作及find方法
public T remove(T element)
{
T result;
int index = find(element);
if (index == NOT_FOUND)
throw new ElementNotFoundException("ArrayList");
result = list[index];
rear--;
// shift the appropriate elements
for (int scan=index; scan < rear; scan++)
list[scan] = list[scan+1];
list[rear] = null;
modCount++;
return result;
}
private int find(T target)
{
int scan = 0;
int result = NOT_FOUND;
if (!isEmpty())
while (result == NOT_FOUND && scan < rear)
if (target.equals(list[scan]))
result = scan;
else
scan++;
return result;
}
- contains操作:這裏也將調用find方法
public boolean contains(T target)
{
return (find(target) != NOT_FOUND);
}
- 添加操作
- 有序列表的add操作
public void add(T element) { if (!(element instanceof Comparable)) throw new NonComparableElementException("OrderedList"); Comparable<T> comparableElement = (Comparable<T>)element; if (size() == list.length) expandCapacity(); int scan = 0; // find the insertion location while (scan < rear && comparableElement.compareTo(list[scan]) > 0) scan++; // shift existing elements up one for (int shift=rear; shift > scan; shift--) list[shift] = list[shift-1]; // insert element list[scan] = element; rear++; modCount++; }
- 無序列表的addAfter操作
public void addAfter(T element, T target) { if (size() == list.length) expandCapacity(); int scan = 0; // find the insertion point while (scan < rear && !target.equals(list[scan])) scan++; if (scan == rear) throw new ElementNotFoundException("UnorderedList"); scan++; // shift elements up one for (int shift=rear; shift > scan; shift--) list[shift] = list[shift-1]; // insert element list[scan] = element; rear++; modCount++; }
9.使用鏈表實現列表
- LinkedList類的類頭、類級函數和構造函數:
public abstract class LinkedList<T> implements ListADT<T>, Iterable<T>
{
protected int count;
protected LinearNode<T> head, tail;
protected int modCount;
/**
* Creates an empty list.
*/
public LinkedList()
{
count = 0;
head = tail = null;
modCount = 0;
}
}
- remove操作
public T remove(T targetElement) throws EmptyCollectionException,
ElementNotFoundException
{
if (isEmpty())
throw new EmptyCollectionException("LinkedList");
boolean found = false;
LinearNode<T> previous = null;
LinearNode<T> current = head;
while (current != null && !found)
if (targetElement.equals(current.getElement()))
found = true;
else
{
previous = current;
current = current.getNext();
}
if (!found)
throw new ElementNotFoundException("LinkedList");
if (size() == 1) // only one element in the list
head = tail = null;
else if (current.equals(head)) // target is at the head
head = current.getNext();
else if (current.equals(tail)) // target is at the tail
{
tail = previous;
tail.setNext(null);
}
else // target is in the middle
previous.setNext(current.getNext());
count--;
modCount++;
return current.getElement();
}
教材學習中的問題和解決過程
問題1:對於書上97頁所提及的“Serializable接口是為了某個對象能使用串行化進行存儲”,什麽是串行化,又是怎麽實現的?
- 問題1解決方案:(1)Java串行化即Java序列化,一個對象隨著創建而存在,隨著程序結束而結束。那如果我要保存一個對象的狀態呢?Java序列化能夠將對象的狀態寫入byte流存儲起來,也從其他地方將byte流讀取出來,重新構造一個新的對象。這種機制允許你將對象通過網絡進行傳播,並且可以隨時把對象持久化到數據庫、文件系統中。簡而言之,序列化就是將一個對象的狀態保存起來,而反序列化就是將已經保存的流對象恢復成原來的對象。
(2)如何實現序列化?
實現序列化有一個條件,即實現序列化的類必須實現java.io.Serializable接口。之後可以利用ObjectInputStream的readOjbect()方法和OjbectOutputStream的writeObject()方法進行對象的讀和寫,即反序列化和序列化。
a) Java對象:在java中要想使一個java對象可以實現序列化與反序列化,必須讓該類實現java.io.Serializable接口,java.io.Serializable接口定義如下:
publicinterface Serializable {
}
b) 序列化主要依賴java.io.ObjectOutputStream類,該類對java.io.FileOutputStream進一步做了封裝,這裏主要使用ObjectOutputStream類的writeObject()方法實現序列化功能
/**
*將對象序列化到磁盤文件中
*@paramo
*@throwsException
*/
publicstaticvoid writeObject(Object o) throws Exception{
File f=new File("d:""user.tmp");
if(f.exists()){
f.delete();
}
FileOutputStream os=new FileOutputStream(f);
//ObjectOutputStream 核心類
ObjectOutputStream oos=new ObjectOutputStream(os);
oos.writeObject(o);
oos.close();
os.close();
}
代碼調試中的問題和解決過程
問題1:Josephus問題中的代碼中numPeople,skip分別代表什麽意思?
問題1解決方案:把書上代碼敲入後,運行了兩次,去對比書上給出的那個7個元素的結果,
這時便可理解numPeople代表總的人數,而skip代表的則是每隔幾個元素刪除一個元素,每3個人在這裏實際上是每隔2個人。
代碼托管
上周代碼行數為8867行,現在為10335行,本周共1468行,
上周考試錯題總結
- 上周沒有錯題
結對及互評
- 本周結對學習情況
- 20172308
博客中值得學習的或問題: 博客中代碼問題解決過程記錄較詳細,可適當添加教材內容總結。
結對學習內容:學習第6章內容——列表
其他(感悟、思考等)
感悟
- 假期學習時間有點短,2號完成了實驗博客,學習了本章內容,之後幾天做的內容不多,下周要投入多的時間。
學習進度條
代碼行數(新增/累積) | 博客量(新增/累積) | 學習時間(新增/累積) | 重要成長 | |
---|---|---|---|---|
目標 | 5000行 | 30篇 | 400小時 | |
第一周 | 0/0 | 1/1 | 15/15 | |
第二周 | 572/572 | 1/2 | 16/31 | |
第三周 | 612/1184 | 1/3 | 13/44 | |
第四周 | 1468/2652 | 2/5 | 13/57 |
參考資料
- Java 列表
- 數據結構(Java)——列表的實現
- java序列化(串行化)
20172302 《Java軟件結構與數據結構》第四周學習總結