Я использую хэш-карту для хранения пар ключ-значение. Когда я использую метод get для получения ключа объекта Identifier с именем «Ape», он корректно возвращает значение объекта Set «1,2,3,4», но когда я пытаюсь получить тот же объект, значение возвращает «».
Я уже пытался убедиться, что я как-то не удаляю пары ключей-значений, и проверяю, создаю ли я каждый раз новую хэш-карту. Когда я распечатываю метод hashmap to string, объект Identifier «Ape» больше не отображается на карте вместе со своим значением.
Извините за большое количество кода! Я не был уверен, добавлять ли все это или нет.
package nl.vu.labs.phoenix.ap;
import java.math.BigInteger;
import java.util.*;
import java.util.regex.Pattern;
import java.io.*;
/**
* A set interpreter for sets of elements of type T
*/
public class Interpreter<T extends SetInterface<BigInteger>> implements InterpreterInterface<T> {
HashMap<IdentifierInterface, T> hm = new HashMap<IdentifierInterface, T>();
@Override
public T getMemory(String v) {
IdentifierInterface i = new Identifier();
i.appendIdentifier(v);
if(hm.containsKey(i)){
return hm.get(i);
}else{
return null;
}
}
@Override
public T eval(String s) {
System.out.println("HASHMAP:"+hm.toString());
Scanner in;
try {
in = format(s);
} catch (APException e1) {
in=new Scanner(s);
}
in.useDelimiter("");
try {
readStatement(in);
}
catch(Exception e) {
return null;
}
return null;
}
char nextChar(Scanner in) {
return in.next().charAt(0);
}
boolean nextCharIs(Scanner in, char c) {
boolean IsMatch = in.hasNext(Pattern.quote(c+""));
return IsMatch;
}
boolean nextCharIsDigit (Scanner in) {
return in.hasNext("[0-9]");
}
boolean nextCharIsLetter (Scanner in) {
return in.hasNext("[a-zA-Z]");
}
void eraseSpace(Scanner in) {
while (nextCharIs(in, ' ')) {
nextChar(in);
}
}
private void checkChar (String in, char a) throws APException {
Scanner token = new Scanner(in);
if (! nextCharIs(token, a)) {
throw new APException("Missing token: " + a);
}
}
private String SetToString(SetInterface<BigInteger> set){
StringBuilder output = new StringBuilder();
if(set.first()){
output.append(set.get());
while(set.next()){
output.append(" ");
output.append(set.get());
}
}
return output.toString();
}
private Scanner format(String statement) throws APException {
Scanner in = new Scanner(statement);
in.useDelimiter("");
StringBuilder line = new StringBuilder();
while (in.hasNext()) {
if (nextCharIs(in, '/')) {
line.append(in.nextLine());
return new Scanner(line.toString());
} else if (nextCharIsLetter(in) || nextCharIsDigit(in)) {
line.append(in.next());
while (nextCharIs(in, ' ')) {
checkChar(in.next(), ' ');
if (nextCharIsLetter(in) || nextCharIsDigit(in)) {
throw new APException("Identifier error: spaces inside identifier not allowed");
}
}
} else if (nextCharIs(in, ' ')) {
checkChar(in.next(), ' ');
} else {
line.append(in.next());
}
}
String formated = line.toString();
for (int i = 0; i < formated.length(); i++) {
if (formated.charAt(i) == ',') {
try {
if (!Character.isDigit(formated.charAt(i - 1)) || !Character.isDigit(formated.charAt(i + 1))) {
throw new APException("no number in set");
}
} catch (Exception e) {
throw new APException("no number in set");
}
} else if (formated.charAt(i) == '0') {
if (!Character.isDigit(formated.charAt(i - 1)) && Character.isDigit(formated.charAt(i + 1))) {
throw new APException("Invalid number");
}
}
}
return new Scanner(line.toString());
}
void readStatement(Scanner in)throws APException{
if (nextCharIsLetter(in)) {
readAssignment(in);
} else if (nextCharIs(in, '?')) {
readPrint_statement(in);
} else if (! nextCharIs(in, '/')){
throw new APException("Invalid statement, please read the documentation");
}
}
void readAssignment(Scanner in) throws APException{
//handle end of line
in.useDelimiter("=");
IdentifierInterface i;
SetInterface<BigInteger> set;
i=readIdentifier(in);
set = readExpression(new Scanner(in.next()));
this.hm.put(i,(T)set);
}
void readPrint_statement(Scanner in)throws APException{
in.useDelimiter("");
if(nextCharIs(in,'(')||nextCharIs(in,'{')||nextCharIsLetter(in)||nextCharIsDigit(in)){
readExpression(in);
}else if (! nextCharIs(in, ';')){
throw new APException("Invalid statement, please read the documentation");
}
}
IdentifierInterface readIdentifier(Scanner in)throws APException{
IdentifierInterface i = new Identifier();
String ident="";
if(in.hasNext()) {
ident+=in.next();
}
System.out.println("readident:"+ident);
i.appendIdentifier(ident);
if(i.hasCorrectIdentifierFormat(i.toString())){
return i;
}else{
throw new APException("Invalid Identifier foramt");
}
}
SetInterface<BigInteger> readExpression(Scanner in)throws APException{
in.useDelimiter("");
SetInterface<BigInteger> term = null;
StringBuilder terms = new StringBuilder();
while (in.hasNext()) {
while(nextCharIs(in, ' ')) {
in.next();
}
//System.out.println("HRE:"+in.next());
if (nextCharIs(in, '+') || nextCharIs(in, '-') || nextCharIs(in, '|')) {
String addOp = in.next();
if (term == null) {
term = readTerm(new Scanner(terms.toString()));
}
terms.setLength(0);
while (in.hasNext()) {
if ((nextCharIs(in, '+') || nextCharIs(in, '-') || nextCharIs(in, '|'))) {
term = addOps(term, readTerm(new Scanner(terms.toString())), addOp);
terms.setLength(0);
break;
} else {
terms.append(in.next());
}
}
if (terms != null) {
term = addOps(term, readTerm(new Scanner(terms.toString())), addOp);
}
} else {
terms.append(in.next());
}
}
if (term == null) {
term = readTerm(new Scanner(terms.toString()));
}
return term;
}
SetInterface<BigInteger> addOps(SetInterface<BigInteger> set1, SetInterface<BigInteger> set2, String op){
System.out.print("addops");
SetInterface<BigInteger> set = new Set<>();
if(op=="+"){
set = set1.union(set2);
}else if(op=="-"){
set = set1.difference(set2);
}else{
set = set1.symmetricDifference(set2);
}
return set;
}
SetInterface<BigInteger> readTerm(Scanner in)throws APException{
in.useDelimiter("");
SetInterface<BigInteger> factor;
StringBuilder factors = new StringBuilder();
while (in.hasNext()) {
if (nextCharIs(in, '*')) {
checkChar(in.next(), '*');
factor = readFactor(new Scanner(factors.toString())).intersection(readTerm(new Scanner(in.nextLine())));
return factor;
} else {
factors.append(in.next());
}
}
factor = readFactor(new Scanner(factors.toString()));
return factor;
}
SetInterface<BigInteger> readFactor(Scanner in)throws APException{
in.useDelimiter("");
SetInterface<BigInteger> resultset = new Set<>();
int complexFactors = 0;
StringBuilder sets = new StringBuilder();
while(in.hasNext()) {
if(nextCharIs(in,' ')){
in.next();
}
if (nextCharIs(in, '(')) {
checkChar(in.next(), '(');
complexFactors += 1;
while (in.hasNext() && complexFactors != 0) {
if (nextCharIs(in, '(')) {
complexFactors += 1;
sets.append(in.next());
} else if (nextCharIs(in, ')')) {
complexFactors -= 1;
sets.append(in.next());
if (complexFactors == 0) {
if (nextCharIs(in,')')) {
throw new APException("Invalid token detected");
}
} else {
if(!in.hasNext()&&complexFactors!=0){
throw new APException("Invalid token detected");
}
else{
sets.append(in.next());
}
}
}else {
sets.append(in.next());
}
}
resultset = readExpression(new Scanner(sets.toString()));
} else if (nextCharIsLetter(in)) {
sets.append(in.next());
while (nextCharIsLetter(in)|| nextCharIsDigit(in)) {
sets.append(in.next());
}
IdentifierInterface i = new Identifier();
i.appendIdentifier(sets.toString());
if (hm.containsKey(i)) {
resultset = hm.get(i);
return resultset;
} else {
throw new APException("Identifier \\\""+ sets.toString() +"\\\" does not correspond to a sets");
}
}
if (nextCharIs(in,'{')) {
checkChar(in.next(), '{');
if (nextCharIs(in,',')) {
throw new APException("no number");
}
while (!nextCharIs(in,'}') && in.hasNext()) {
sets.append(in.next());
}
if (in.hasNext()) {
checkChar(in.next(), '}');
} else {
throw new APException("Invalid token");
}
if (in.hasNext()) {
throw new APException("Operator or end of line missing");
}
resultset = readSet(sets.toString());
} else {
throw new APException("Invalid statement detected");
}
}
if (complexFactors != 0) {
throw new APException("Missing parenthesis detected");
}
return resultset;
}
SetInterface<BigInteger> readSet(String nums)throws APException{
SetInterface<BigInteger> set = new Set<>();
Scanner in = new Scanner(nums);
in.useDelimiter(",");
while (in.hasNext()) {
try {
set.add(in.nextBigInteger());
} catch (Exception e) {
throw new APException("Invalid number detected in a set");
}
}
in.close();
//set.fixDoubles();
return set;
}
}
public void parenthesisBalanceTests() {
InterpreterInterface<Set<BigInteger>> interpreter = new Interpreter<Set<BigInteger>>();
interpreter.eval("Ape = {1, 2, 3, 4, 5, 6, 7, 8, 9}");
// missing closing parenthesis test
interpreter.eval("Ape = (({1, 2, 3})");
SetInterface<BigInteger> actual = interpreter.getMemory("Ape");
System.out.print("ACTRUAL:"+actual);
ArrayList<BigInteger> expected = convertExpectedList("1 2 3 4 5 6 7 8 9");
assertTrue("missing closing parenthesis' should result in an exception", compareSets(actual, expected));
// missing opening parenthesis test
interpreter.eval("Ape = ({1, 2, 3}))");
actual = interpreter.getMemory("Ape");
assertTrue("missing opening parenthesis' should result in an exception", compareSets(actual, expected));
}
Это тесты, которые я должен пройти в parenthesisBalcenceTest (). Отсутствует закрывающая скобка проходит успешно, потому что фактическое значение возвращает «1 2 3 4 5 6 7 8 9», но отсутствует открывающая скобка, потому что фактическое значение равно «».