diff options
Diffstat (limited to 'src/de/ostfalia/algo/ws18/s1/Management.java')
| -rw-r--r-- | src/de/ostfalia/algo/ws18/s1/Management.java | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/src/de/ostfalia/algo/ws18/s1/Management.java b/src/de/ostfalia/algo/ws18/s1/Management.java new file mode 100644 index 0000000..940a0ad --- /dev/null +++ b/src/de/ostfalia/algo/ws18/s1/Management.java @@ -0,0 +1,275 @@ +package de.ostfalia.algo.ws18.s1; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.function.Predicate; + +import de.ostfalia.algo.ws18.base.IManagement; +import de.ostfalia.algo.ws18.base.IMember; +import de.ostfalia.algo.ws18.base.KindOfSport; +import de.ostfalia.algo.ws18.base.Member; + +public class Management implements IManagement { + /** + * Track the number of operations. + */ + protected int numberOfOperations; + + /** + * Track the execution time. + */ + private long lastCheckpointNs; + + /** + * Current head node. + */ + protected LinkedListNode<IMember> head; + /** + * Length of the list. + */ + protected int size = 0; + /** + * Whether the list is reversed, i. e. the head is the tail. + */ + private boolean reversed = false; + + /** + * Empty constructor. + */ + public Management() { + } + + /** + * Insert from an array of strings. + * + * @param membersCsv Array of CSV rows. + */ + public Management(String[] membersCsv) { + for (String memberCsv : membersCsv) { + this.insert(new Member(memberCsv)); + } + } + + /** + * Read from the CSV file and insert. + * + * @param filename Path to the CSV file. + */ + public Management(String filename) { + this.importFromFile(filename); + } + + /** + * Read from the CSV file and insert. + * + * @param filename Path to the CSV file. + */ + public void importFromFile(String filename) { + File file = new File(filename); + + try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) { + bufferedReader.lines().forEach(line -> insert(new Member(line))); + } catch (IOException exception) { + throw new IllegalArgumentException(exception); + } + } + + /** + * Create a filtered version of this list. + * + * @param criteria Criteria to filter for. + * @param breakAfterFirstMatch If true, return after the first match. + * @return A new list where all elements meet the given criteria. + */ + protected Management filter(Predicate<IMember> criteria, boolean breakAfterFirstMatch) { + Management result = new Management(); + if (this.size == 0) { + return result; + } + + // searches from head, inserts at head -> result is reversed + result.reverse(); + + LinkedListNode<IMember> currentNode = this.head; + do { + IMember currentValue = currentNode.getValue(); + this.numberOfOperations++; + if (criteria.test(currentValue)) { + result.insert(currentValue); + if (breakAfterFirstMatch) { + break; + } + } + } while ((currentNode = currentNode.getNext()) != null); + + return result; + } + + /** + * Find the first element that matches the given criteria. + * + * @param criteria Criteria to search for. + * @return The first element that matches the given criteria or null. + */ + protected LinkedListNode<IMember> search(Predicate<IMember> criteria) { + Management filteredList = this.filter(criteria, true); + if (filteredList.size() == 0) { + return null; + } else { + return filteredList.head; + } + } + + /** + * Count the number of elements that match the given criteria. + * + * @param criteria Criteria to filter for. + * @return The number of elements that match the given criteria. + */ + private long size(Predicate<IMember> criteria) { + return this.filter(criteria, false).size; + } + + /** + * Reverse the order of the list. + */ + public void reverse() { + this.reversed = !this.reversed; + } + + /** + * @return The length of this list. + */ + @Override + public int size() { + return this.size; + } + + /** + * Add an element at the start of the list. + * Replace the current head with a new node and link this node to the old head. + * + * @return TODO? + */ + @Override + public boolean insert(IMember value) { + LinkedListNode<IMember> newHead = new LinkedListNode<IMember>(value); + this.numberOfOperations++; + if (this.head != null) { + newHead.setNext(this.head); + } + this.head = newHead; + + this.size++; + return true; // TODO? + } + + /** + * Find the first member with the given key. + * + * @param key The key to search for. + * @return The member or null. + */ + @Override + public IMember search(long key) { + LinkedListNode<IMember> result = this.search(member -> member.getKey() == key); + if (result != null) { + return result.getValue(); + } else { + return null; + } + } + + /** + * Find the first member with the given name. + * + * @param name The name of the member. + * @param firstName first name of the member. + * @return The member or null. + */ + @Override + public IMember search(String name, String firstName) { + LinkedListNode<IMember> result = this.search(member -> member.getName().equals(name) + && member.getFirstName().equals(firstName)); + if (result != null) { + return result.getValue(); + } else { + return null; + } + } + + /** + * Count the number of members which have an association to the given kindOfSport. + * + * @param kindOfSport The kindOfSport of the members. + * @return The number of members with the given kindOfSport. + */ + @Override + public int size(KindOfSport kindOfSport) { + this.numberOfOperations = 0; + return (int) this.size(member -> member.getKindOfSport().equals(kindOfSport)); + } + + /** + * Return the members which have an association to the given kindOfSport. + * + * @param kindOfSport The kindOfSport of the members. + * @return An array of the members with the given kindOfSport. + */ + @Override + public IMember[] discipline(KindOfSport kindOfSport) { + return this.filter(member -> member.getKindOfSport().equals(kindOfSport), false) + .toArray(); + } + + /** + * Convert the list to an array. + * + * @return The elements of this list as array. + */ + @Override + public IMember[] toArray() { + IMember[] array = new IMember[this.size]; + if (this.size() == 0) { + return array; + } + + LinkedListNode<IMember> currentNode = this.head; + + for (int index = 0; index < this.size; index++) { + if (reversed) { + array[this.size - index - 1] = currentNode.getValue(); + } else { + array[index] = currentNode.getValue(); + } + currentNode = currentNode.getNext(); + } + + return array; + } + + /** + * TODO + * + * @return The number of operations recorded since the last call. + */ + @Override + public int numberOfOperations() { + int numberOfOperations = this.numberOfOperations; + this.numberOfOperations = 0; + return numberOfOperations; + } + + /** + * Reset the timer and get the time difference in ns. + * + * @return Nanoseconds since the last call. + */ + public long checkpoint() { + long nanoseconds = this.lastCheckpointNs; + this.lastCheckpointNs = System.nanoTime(); + return this.lastCheckpointNs - nanoseconds; + } +} |
