我正在尝试为要存储少量数据(<1000个键值)时包含序列的类编写ADT,否则使用HashTable。我必须自己编写序列类,但我很高兴发现java在HashTable类中内置了它自己。但是,此ADT的要求之一是它必须能够显示上一个和下一个键(在代码中称为VIN)。我可以使用序列类轻松地做到这一点,但是我想知道内置的HashTable类是否具有这样的功能。我将不得不编写自己的HashTable类,还是有一种无需这样做即可实现目标的方法?谢谢大家的事先帮助,我非常感谢!
这是CVR类(将数据传递给此类,并调用序列或HastTable类)
import java.util.*;
public class CVR
{
//this will be used to generate random alpha numeric numbers
private final static String alphaNumeric="ABDCEFGHIJKLMNOPQRSTUVWXYZ0123456789";
//key
private String VIN;
//threshold (determines which ADT to use)
private int threshold;
//length of key
private int VINLength;
//this is an object of Archive which will hold the data associated with VIN
private Account value;
//TBD
//private Collection<Account> activeVINS;
//HashMap to store all the key-value pairs
//the value come in the form of a stack because,
//multiple events can be associated with the same
//VIN, and must be shown in reverse-chronological order
private Hashtable<String, Stack<Account>> hashRecords;
private sequence seqRecords;
//This will keep track of all VINs and make sure
//none of them are repeated
private HashSet<String> VINRecorder;
private boolean hashTabl=false;
//default constructor
public CVR(int threshold) throws Exception
{
this.setThreshold(threshold);
if (threshold>1000)
{
hashRecords=new Hashtable<>();
hashTabl=true;
}
else
{
seqRecords=new sequence();
hashTabl=false;
}
}
//not sure this is even needed
//parameterized constructor for CVR, takes VIN
//and adds it to VINRecorder
//re-evaluate this method, with this a VIN is added to HashSet, but not to
//HashMap. At the same time I'm not sure We want VINs w/o associated accounts
//to be in HashMap. TBD
//For now actually, I will add them to HashMap, this may change down the line...
/**
public CVR (String VIN) throws Exception
{
this.VIN=VIN;
records=new Hashtable<>();
VINRecorder=new HashSet<>();
add(VIN, null);
//Stack<Account> stack = new Stack<Account>();
//VINRecorder.add(VIN);
}
**/
//accessors and mutators
//VIN getters and setters
public String getVIN()
{
return VIN;
}
public void setVIN(String VIN)
{
this.VIN=VIN;
VINRecorder=new HashSet<>();
VINRecorder.add(VIN);
}
//threshold getters and setters
public int getThreshold()
{
return threshold;
}
//for this one we have to keep in mind the restriction set
//on us in the instructions
public void setThreshold(int threshold) throws Exception
{
if(threshold<100 || threshold>900000)
{
//System.out.println("Invalid input for threshold");
throw new Exception("Invalid input for threshold");
}
else
{
this.threshold=threshold;
}
}
//VINLength getters and setters
public int getVINLength()
{
return VINLength;
}
//again for this one. we need to take the
//instructions into account for this special
//case
public void setVINLength(int VINLength) throws Exception
{
if(VINLength<10 || VINLength>17)
{
throw new Exception("Invalid input for VIN length");
}
else
{
this.VINLength=VINLength;
}
}
//Now onto the methods
//Generate method
//This method should randomly generate a sequence
//containing n new non-existing valid keys
//***Must determine whether the output is a sequence or not
public String generate(int size) throws Exception
{
char[] Arr= alphaNumeric.toCharArray();
String[] ender=new String[size];
//generating random number between 10 and 17
Random r= new Random();
int low=10;
int high=17;
for(int x=0; x<size;x++)
{
int highLow=r.nextInt(high-low)+10;
StringBuilder newString=new StringBuilder();
//making string between length of 10 and 17 randomly
for(int i=0; i<highLow; i++)
{
newString.append(Arr[new Random().nextInt(Arr.length)]);
}
///////////////////
String newVIN=newString.toString();
//System.out.println(newVIN);
//This must be further explored, I do not know why,
//but for some reason it does not work if the first
//condition is not there, to be explored
if(newVIN!=null)
{
}
//stops here for some reason, must find out why, something is wrong with this statement
else if(VINRecorder.contains(newVIN))
{
x--;
}
else
{
ender[x]=newString.toString();
}
ender[x]=newString.toString();
}
//System.out.println("hello");
System.out.println(Arrays.toString(ender));
return Arrays.toString(ender);
}
//method allKeys
//this method should return all keys as a sorted
//sequence in lexicographic order
//the plan here is to use
/**
public LinkedList<Account> allKeys()
{
}
**/
//add method
//****must check to see if must be resized later
public void add(String VIN, Account value) throws Exception
{
if(hashTabl==true)
{
if(!VIN.equals(value.getVIN()))
{
System.out.println("Something went wrong :/");
throw new Exception("VIN does not match account");
}
else if(hashRecords.containsKey(VIN))
{
System.out.println("VIN exists, adding to record");
hashRecords.get(VIN).add(value);
System.out.println("Success!");
}
else
{
System.out.println("New account made, record added!");
Stack<Account> stack = new Stack<Account>();
stack.add(value);
hashRecords.put(VIN, stack);
System.out.println("Success!");
//resize here
//
}
}
else
{
if(value==null)
{
Account saveVIN=new Account(VIN);
seqRecords.add(saveVIN);
}
seqRecords.add(value);
}
}
//remove method
//***must check to see if must be resized later
public void remove(String VIN)
{
if(hashTabl==true)
{
if(hashRecords.containsKey(VIN))
{
hashRecords.remove(VIN);
//resize here
//
}
else
{
System.out.println("Key does not exist in HashTable");
}
}
else
{
seqRecords.removeVIN(VIN);
}
}
//getValues method
public Stack<Account> getValues(String VIN)
{
if(hashTabl == true)
{
if(hashRecords.containsKey(VIN))
{
Stack<Account> values = new Stack<Account>();
values=hashRecords.get(VIN);
return values;
}
else
{
System.out.println("This VIN could not be found in directory");
return null;
}
}
else
{
return seqRecords.getAccount(VIN);
}
}
//nextKey methods
public String nextVIN(String VIN)
{
//unfinished, not sure what to call here
if(hashTabl=true)
{
return hashRecords.
}
else
{
return seqRecords.nextVIN(VIN);
}
}
//previous Accidents method
public Stack<Account> prevAccids(String VIN)
{
if(hashTabl == true)
{
if(hashRecords.contains(VIN))
{
Stack<String> Accids= new Stack<String>();
Stack<Account> temp; //= new Stack<Account>();
temp=hashRecords.get(VIN);
return temp;
/**
String tempString;
while(!temp.isEmpty())
{
tempString=temp.pop().getAccids();
Accids.push(tempString);
}
temp=null;
return Accids;
**/
}
return null;
}
else
{
Stack<Account> temp;
temp=seqRecords.getAccount(VIN);
if(temp==null || temp.isEmpty())
{
System.out.println("This VIN does not exist in the sequence");
return null;
}
else
{
return temp;
}
}
}
//driver method
public static void main(String[] args) throws Exception
{
CVR hello= new CVR(100);
try
{
//System.out.println("hello");
//hello.generate(5);
Account abdcg=new Account("adsj4jandnj4", "Muhammad Ferreira", "perfect record");
Account abdcg1=new Account("adsj4jandnj4","Myriam Ferreira", "Fender Bender");
Account abdcg2= new Account("adsj4jandnj4", null, null);
/////
hello.add("adsj4jandnj4", abdcg);
hello.add("adsj4jandnj4", abdcg2);
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这是我的序列类
import java.util.ArrayList;
import java.util.Stack;
public class sequence
{
private class position
{
private Stack<Account> stack;
private int index;
//constructors
public position()
{
this.stack=new Stack<Account>();
this.index=0;
}
public position(int index, Account acc)
{
this.index=index;
this.stack=new Stack<Account>();
stack.push(acc);
}
//muatators
public int getIndex()
{
return index;
}
public void setIndex(int index)
{
this.index=index;
}
public Stack<Account> getStack()
{
return stack;
}
public void setStack(Stack<Account> newStack)
{
this.stack=newStack;
}
}
private int size;
//private int tail;
private int elementsNum;
//private int currentIndex;
private ArrayList<position> Arr;
public sequence()
{
//currentIndex=0;
size=0;
Arr= new ArrayList<position>(); ;
}
//add first method
public void add(Account account)
{
for(int i=0; i<size; i++)
{
//if already in array, push into its stack
if((Arr.get(i).getStack().peek().getVIN()).equals(account.getVIN()))
{
Arr.get(i).getStack().push(account);
break;
}
//if not in array, make new entry for it
else if(!(Arr.get(i).getStack().peek().getVIN()).equals(account.getVIN()) && i==size-1)
{
position added=new position(size, account);
Arr.add(added);
//currentIndex++;
size++;
}
}
}
//addIndex
//don't think this method is necessary for assignment
/**
public void addIndex(int ind, Account account)
{
position added=new position(ind, account);
Arr.add(ind, added);
size++;
//update indexes of position node
updateIndex();
}
*/
//resizeArray and updates index
public void resize()
{
Arr.trimToSize();
updateIndex();
}
//remove method
public void removeVIN(String VIN)
{
for (int i=0; i<size; i++)
{
if(size==0 || (!VIN.equals(Arr.get(i).getStack().peek().getVIN()) && i==size-1))
{
System.out.println("The Sequence does not contain this VIN");
break;
}
else if(VIN.equals(Arr.get(i).getStack().peek().getVIN()))
{
Arr.remove(i);
resize();
size--;
System.out.println("Successfully removed " +VIN+" and associated values");
}
}
}
//update indexes
public void updateIndex()
{
for (int i=0; i<size; i++)
{
if(Arr.get(i).getIndex() != i)
{
Arr.get(i).setIndex(i);
}
}
}
//Get Values
//Will be used in CVR for both the getValues method (return all values)
//and prevAccids method (return only the accidents not entire account)
public Stack<Account> getAccount(String VIN)
{
for (int i=0; i<size; i++)
{
if(size==0)
{
System.out.println("The Sequence is empty");
break;
}
else if(VIN.equals(Arr.get(i).getStack().peek().getVIN()))
{
return Arr.get(i).getStack();
}
}
return null;
}
//get previous VIN method
public String preVIN(String VIN)
{
for (int i=0; i<size; i++)
{
if((Arr.get(i).getStack().peek().getVIN()).equals(VIN))
{
if(i==0)
{
return "There is no previous VIN, this is the first one";
}
return Arr.get(i-1).getStack().peek().getVIN();
}
}
return null;
}
//get next VIN method
public String nextVIN(String VIN)
{
for (int i=0; i<size; i++)
{
if((Arr.get(i).getStack().peek().getVIN()).equals(VIN))
{
if(i==size-1)
{
return "There is no next VIN, this is the last one";
}
return Arr.get(i+1).getStack().peek().getVIN();
}
}
return null;
}
}
最后,这是我的Account类
//this method is similar to a node, contains
//VIN, Owner, Accidents details
public class Account
{
private String VIN;
private String owner;
private String accidents;
public Account() {};
public Account(String VIN)
{
this.VIN=VIN;
this.owner=null;
this.accidents=null;
}
public Account(String VIN, String owner, String accidents)
{
this.VIN=VIN;
this.owner=owner;
this.accidents=accidents;
}
//mutators
public void setVIN(String VIN)
{
this.VIN=VIN;
}
public String getVIN()
{
return VIN;
}
public void setOwner(String owner)
{
this.owner=owner;
}
public String getOwner()
{
return owner;
}
public void setAccids(String accidents)
{
this.accidents=accidents;
}
public String getAccids()
{
return accidents;
}
}
您可能想使用TreeMap
而不是过时的Hashtable-它是按设计按键排序的。