Может ли встроенный класс HashTable показывать предыдущий и следующий ключи? - PullRequest
1 голос
/ 19 апреля 2020

Я пытаюсь написать ADT для класса, который включает последовательность, когда имеется небольшой объем данных для хранения (<1000 ключевых значений) и использует HashTable в противном случае. Я должен написать класс последовательности сам, но я был рад узнать, что java имеет собственный встроенный класс HashTable. Однако одно из требований к этому ADT - то, что он должен иметь возможность отображать предыдущий и следующий ключи (называемые VIN-кодами в коде). Я могу сделать это легко с моим классом последовательности, однако мне было интересно, если встроенный класс HashTable имеет такую ​​функцию. Должен ли я написать свой собственный класс HashTable или есть способ, которым я могу достичь своей цели, не делая этого? Заранее всем спасибо за помощь, я очень ценю это! </p>

Это класс 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;
    } 


}

Наконец, это мой класс учетной записи

 //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;
    }

}

1 Ответ

1 голос
/ 19 апреля 2020

Возможно, вы захотите использовать TreeMap вместо устаревшей Hashtable - она ​​сортируется по ключу по конструкции и предоставляет методы для получения последовательности ключей и связанных значений:

  • K firstKey()
  • K lastKey()
  • K higherKey(K key)
  • K lowerKey(K key) et c.
...