2010-04-09 13 views
109

Ich habe eine Zeichenfolge wie folgen aus:Gibt es in Java eine eval() - Funktion?

String str = "4*5"; 

Jetzt muß ich das Ergebnis von 20 erhalten, indem Sie die Zeichenfolge verwenden.

Ich weiß in einigen anderen Sprachen die eval() Funktion wird dies tun. Wie kann ich das in Java machen?

+0

ich für diese Aufgabe über Java würde vorschlagen, zu vergessen und Clojure verwenden. Clojure ermöglicht es Ihnen, zu analysieren und/oder Code zur Laufzeit kompilieren (und bei der Kompilierung) und führen Sie es, und auch den Code während der Kompilierung zu erzeugen, wie auch viele andere Dinge, die sind, die übrigens ziemlich üblich in der LISP Welt. Java ist zu langweilig. Und Clojure kann alles, was Java kann, weil sie auf JVM läuft (obwohl andere Implementierungen existieren, auch) Und es kann nahtlos mit Java gemischt werden, sogar in einem gemeinsamen Projekt. –

+2

Dies ist * nicht * ein Duplikat einer Frage zu stellen [wie ein arithmetischen Ausdruck auszuzuwerten] (http://stackoverflow.com/questions/3422673/evaluating-a-math-expression-given-in-string-form), weil es _specificifically_ fragt nach eval(). – Raedwald

Antwort

117

Sie können die ScriptEngine-Klasse verwenden und sie als JavaScript-Zeichenfolge auswerten.

ScriptEngineManager manager = new ScriptEngineManager(); 
ScriptEngine engine = manager.getEngineByName("js"); 
Object result = engine.eval("4*5"); 

Es mag einen besseren Weg geben, aber dieser funktioniert.

+20

Das Laden eines ganzen JavaScript-Interpreters, um etwas Mathe zu tun, scheint eine riesige Verschwendung zu sein. Aber du hast recht, es funktioniert, besonders wenn Effizienz keine Priorität ist. –

+68

Zusätzlich zu etwas Overkill, öffnet der JavaScript-Interpreter die Code-Injektion. Wenn Sie den Ausdruck nicht genau kontrollieren, könnte Ihnen jemand "while (true) {3 + 4;}" senden und Ihre JVM aufhängen. – Thilo

+2

Es ist effizient in Bezug auf die Codierungszeit. Wenn Sie es die ganze Zeit verwenden, könnten Sie es im Gedächtnis behalten, vielleicht in einem Singleton-Objekt. –

6

Nein, Sie können kein generisches "eval" in Java (oder einer kompilierten Sprache) haben. Es sei denn, Sie sind bereit, einen Java-Compiler UND eine JVM zu schreiben, die innerhalb Ihres Java-Programms ausgeführt werden soll.

Ja, Sie können eine Bibliothek haben, um numerische algebraische Ausdrücke wie den obigen auszuwerten - see this thread for discussion.

40

Es gibt keine Standard-Java-Klasse oder -Methode, die das macht, was Sie wollen. Zu den Optionen gehören:

  • Wählen Sie eine Bibliothek für Ausdrucksexpression von Drittanbietern aus, und verwenden Sie sie. Zum Beispiel JEL oder eines der halbes Dutzend Bibliotheken aufgeführt here.

  • Umbrechen Sie den Ausdruck im Java-Quellcode für eine Klasse mit einer eval-Methode, senden Sie diese an den Java-Compiler und laden Sie dann die resultierende kompilierte Klasse.

  • Verwenden Sie eine Skriptsprache, die von Java als Ausdrucksauswerter aufgerufen werden kann. Möglichkeiten umfassen Javascript, BeanShell und so weiter.

  • Schreiben Sie Ihren eigenen Ausdruckauswerter von Grund auf neu.

Der erste Ansatz ist wahrscheinlich am einfachsten. Der zweite und der dritte Ansatz stellen ein potenzielles Sicherheitsrisiko dar, wenn der Ausdruck von einem nicht vertrauenswürdigen Benutzer ausgewertet wird. (Think-Code-Injektion.)

0

Es gibt nichts, was dies in JavaSE tun würde; Sie müssen Bibliotheken von Drittanbietern finden oder eigene Bibliotheken erstellen.

+1

Es ist eine falsche Antwort! – user2284570

5

Wie vorherige Antworten gibt es dafür keine Standard-API in Java.

Sie können groovy jar Dateien zu Ihrem Pfad hinzufügen und groovy.util.Eval.me ("4 * 5") erledigt Ihre Arbeit.

+4

Gleiche Code-Injektionsprobleme wie bei der Verwendung von JavaScript. – Thilo

+0

Es gibt. 'ScriptEngine'. – EJP

+2

Überprüfen Sie das Datum der Antwort. – Adi

25

Es gibt nur sehr wenige echte Anwendungsfälle, in denen ein String als Fragment von Java-Code bewerten zu können, ist notwendig oder wünschenswert . Das heißt, zu fragen, wie dies zu tun ist wirklich ein XY problem: Sie haben tatsächlich ein anderes Problem, das eine andere Art und Weise gelöst werden kann.

Zuerst sich fragen, woher diese String, die Sie wollen von bewerten kommen? Hat ein anderer Teil Ihres Programms das Programm generiert oder wurde es vom Benutzer bereitgestellt?

  • Ein anderer Teil meines Programms erzeugt es: so, Sie ein Teil des Programms soll die Art der Operation zu entscheiden, zu erfüllen, aber den Vorgang nicht ausführen, und einen zweiten Teil, der die gewählte Operation durchführt . Statt zu erzeugen und dann ein String Auswertung, verwenden Sie die Strategy, Command oder Builder Entwurfsmuster, je nach Ihrem speziellen Fall.

  • Es ist eine Benutzereingabe: Der Benutzer könnte Eingang etwas, einschließlich Befehle, die, wenn sie ausgeführt werden, das Programm dazu führen könnten, sich schlecht benehmen, crash, aussetzen Informationen, die geheim sein sollte, Schaden persistenten Daten (wie die Inhalt einer Datenbank) und andere solche Gemeinheiten. Der einzige Weg, dies zu verhindern, wäre, das String selbst zu analysieren, zu überprüfen, ob es nicht bösartig ist, und es dann zu bewerten. Aber es selbst zu analysieren ist viel von der Arbeit, die die angeforderte eval Funktion tun würde, so dass Sie nichts selbst gespeichert haben. Noch schlimmer ist, dass willkürliche Java Überprüfung nicht bösartig war, ist unmöglich, denn das ist die halting problem ist zu prüfen.

  • Es ist eine Benutzereingabe, aber die Syntax und Semantik der erlaubten Text zu bewerten ist stark eingeschränkt: Keine Allzweck Einrichtung einen Allzweck-Parser leicht umsetzen können und Auswerter für das, was Syntax beschränkt und Semantik Sie gewählt haben. Was Sie tun müssen, ist ein Parser und ein Evaluator für Ihre gewählte Syntax und Semantik zu implementieren. Wenn die Aufgabe einfach ist, könnten Sie einen einfachen recursive-descent oder endlichen Automatenparser von Hand schreiben. Wenn die Aufgabe schwierig ist, können Sie mit einem compiler-compiler (z. B. ANTLR) einen Teil der Arbeit für Sie erledigen.

  • Ich möchte nur einen Desktop-Rechner implementieren!: Eine Hausaufgabe, oder? Wenn Sie die Auswertung des Eingabeausdrucks mit einer bereitgestellten eval Funktion implementieren könnten, wäre das keine Hausaufgabe, oder? Ihr Programm würde drei Zeilen lang sein. Ihr Lehrer erwartet wahrscheinlich, dass Sie den Code für einen einfachen arithmetischen Parser/Evaluator schreiben. Es gibt einen bekannten Algorithmus, shunting-yard, den Sie vielleicht nützlich finden.

7

Ich könnte Ihnen empfehlen, Exp4j zu verwenden. Es ist leicht zu verstehen, wie Sie aus dem folgenden Beispielcode sehen:

Expression e = new ExpressionBuilder("3 * sin(y) - 2/(x - 2)") 
    .variables("x", "y") 
    .build() 
    .setVariable("x", 2.3) 
    .setVariable("y", 3.14); 
double result = e.evaluate(); 
0

Eine unterhaltsame Art und Weise Ihr Problem zu lösen könnte eine Funktion eval() auf eigener Faust seine Codierung! Ich habe es für dich getan!

können Sie FunctionSolver Bibliothek verwenden Sie einfach durch FunctionSolver.solveByX eingeben (Funktion, Wert) in Ihrem Code. Die Funktion Attribut ist ein String, der die Funktion, die Sie lösen möchten darstellt, der Wert Attribut der Wert der unabhängigen Variablen Ihrer Funktion ist (die x sein muss).

Wenn Sie eine Funktion lösen wollen, die mehr als eine unabhängige Variable enthält, Sie FunctionSolver.solve (Funktion, Werte) verwenden können wo die Werte Attribut ein HashMap(String,Double) ist, die alle unabhängig enthält Attribute (als Strings) und ihre jeweiligen Werte (als Double).

Ein weiteres Stück Information: Ich habe eine einfache Version von FunctionSolver, codiert, so dass ihre Träger nur Math methods die einen doppelten Wert zurück und die eine oder zwei Doppel Werte als Felder akzeptiert (nur FunctionSolver.usableMathMethods() verwenden, wenn Sie neugierig sind) (Diese Methoden sind: bs, sin, cos, tan, atan2, sqrt, log, log10, pow, exp, min, max, copySign, signum, IEEEremainder, acos, asin, atan, cbrt , ceil, cosh, expm1, Boden, hypot, log1p, nextAfter, Nextdown, NextUp, gelegentlich, RINT, sinh, tanh, toDegrees, toRadians, ULP). Außerdem unterstützt diese Bibliothek die folgenden Operatoren: */+ -^(auch wenn Java den Operator^normalerweise nicht unterstützt).

Eine letzte Sache: Beim Erstellen dieser Bibliothek musste ich reflections verwenden, um Math methods zu rufen. Ich denke, es ist wirklich cool, nur have a look at this wenn Sie interessiert sind!

Das ist alles, hier ist es der Code (und die library):

package core; 

import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Method; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.HashMap; 

public abstract class FunctionSolver { 

public static double solveNumericExpression (String expression) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { 
    return solve(expression, new HashMap<>()); 
} 

public static double solveByX (String function, double value) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { 

    HashMap<String, Double> values = new HashMap<>(); 
    values.put("x", value); 
    return solveComplexFunction(function, function, values); 
} 

public static double solve (String function, HashMap<String,Double> values) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { 

    return solveComplexFunction(function, function, values); 
} 

private static double solveComplexFunction (String function, String motherFunction, HashMap<String, Double> values) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { 

    int position = 0; 
    while(position < function.length()) { 
     if (alphabetic.contains(""+function.charAt(position))) { 
      if (position == 0 || !alphabetic.contains(""+function.charAt(position-1))) { 
       int endIndex = -1; 
       for (int j = position ; j < function.length()-1 ; j++) { 
        if (alphabetic.contains(""+function.charAt(j)) 
          && !alphabetic.contains(""+function.charAt(j+1))) { 
         endIndex = j; 
         break; 
        } 
       } 
       if (endIndex == -1 & alphabetic.contains(""+function.charAt(function.length()-1))) { 
        endIndex = function.length()-1; 
       } 
       if (endIndex != -1) { 
        String alphabeticElement = function.substring(position, endIndex+1); 
        if (Arrays.asList(usableMathMethods()).contains(alphabeticElement)) { 
         //Start analyzing a Math function 
         int closeParenthesisIndex = -1; 
         int openedParenthesisquantity = 0; 
         int commaIndex = -1; 
         for (int j = endIndex+1 ; j < function.length() ; j++) { 
          if (function.substring(j,j+1).equals("(")) { 
           openedParenthesisquantity++; 
          }else if (function.substring(j,j+1).equals(")")) { 
           openedParenthesisquantity--; 
           if (openedParenthesisquantity == 0) { 
            closeParenthesisIndex = j; 
            break; 
           } 
          }else if (function.substring(j,j+1).equals(",") & openedParenthesisquantity == 0) { 
           if (commaIndex == -1) { 
            commaIndex = j; 
           }else{ 
            throw new IllegalArgumentException("The argument of math function (which is "+alphabeticElement+") has too many commas"); 
           } 
          } 
         } 
         if (closeParenthesisIndex == -1) { 
          throw new IllegalArgumentException("The argument of a Math function (which is "+alphabeticElement+") hasn't got the closing bracket)"); 
         } 
         String functionArgument = function.substring(endIndex+2,closeParenthesisIndex); 
         if (commaIndex != -1) { 
          double firstParameter = solveComplexFunction(functionArgument.substring(0,commaIndex),motherFunction,values); 
          double secondParameter = solveComplexFunction(functionArgument.substring(commaIndex+1),motherFunction,values); 
          Method mathMethod = Math.class.getDeclaredMethod(alphabeticElement, new Class<?>[] {double.class, double.class}); 
          mathMethod.setAccessible(true); 
          String newKey = getNewKey(values); 
          values.put(newKey, (Double) mathMethod.invoke(null, firstParameter, secondParameter)); 
          function = function.substring(0, position)+newKey 
             +((closeParenthesisIndex == function.length()-1)?(""):(function.substring(closeParenthesisIndex+1))); 
         }else { 
          double firstParameter = solveComplexFunction(functionArgument, motherFunction, values); 
          Method mathMethod = Math.class.getDeclaredMethod(alphabeticElement, new Class<?>[] {double.class}); 
          mathMethod.setAccessible(true); 
          String newKey = getNewKey(values); 
          values.put(newKey, (Double) mathMethod.invoke(null, firstParameter)); 
          function = function.substring(0, position)+newKey 
             +((closeParenthesisIndex == function.length()-1)?(""):(function.substring(closeParenthesisIndex+1))); 
         } 
        }else if (!values.containsKey(alphabeticElement)) { 
         throw new IllegalArgumentException("Found a group of letters ("+alphabeticElement+") which is neither a variable nor a Math function: "); 
        } 
       } 
      } 
     } 
     position++; 
    } 
    return solveBracketsFunction(function,motherFunction,values); 
} 

private static double solveBracketsFunction (String function,String motherFunction,HashMap<String, Double> values) throws IllegalArgumentException{ 

    function = function.replace(" ", ""); 
    String openingBrackets = "([{"; 
    String closingBrackets = ")]}"; 
    int parenthesisIndex = 0; 
    do { 
     int position = 0; 
     int openParenthesisBlockIndex = -1; 
     String currentOpeningBracket = openingBrackets.charAt(parenthesisIndex)+""; 
     String currentClosingBracket = closingBrackets.charAt(parenthesisIndex)+""; 
     if (contOccouranceIn(currentOpeningBracket,function) != contOccouranceIn(currentClosingBracket,function)) { 
      throw new IllegalArgumentException("Error: brackets are misused in the function "+function); 
     } 
     while (position < function.length()) { 
      if (function.substring(position,position+1).equals(currentOpeningBracket)) { 
       if (position != 0 && !operators.contains(function.substring(position-1,position))) { 
        throw new IllegalArgumentException("Error in function: there must be an operator following a "+currentClosingBracket+" breacket"); 
       } 
       openParenthesisBlockIndex = position; 
      }else if (function.substring(position,position+1).equals(currentClosingBracket)) { 
       if (position != function.length()-1 && !operators.contains(function.substring(position+1,position+2))) { 
        throw new IllegalArgumentException("Error in function: there must be an operator before a "+currentClosingBracket+" breacket"); 
       } 
       String newKey = getNewKey(values); 
       values.put(newKey, solveBracketsFunction(function.substring(openParenthesisBlockIndex+1,position),motherFunction, values)); 
       function = function.substring(0,openParenthesisBlockIndex)+newKey 
          +((position == function.length()-1)?(""):(function.substring(position+1))); 
       position = -1; 
      } 
      position++; 
     } 
     parenthesisIndex++; 
    }while (parenthesisIndex < openingBrackets.length()); 
    return solveBasicFunction(function,motherFunction, values); 
} 

private static double solveBasicFunction (String function, String motherFunction, HashMap<String, Double> values) throws IllegalArgumentException{ 

    if (!firstContainsOnlySecond(function, alphanumeric+operators)) { 
     throw new IllegalArgumentException("The function "+function+" is not a basic function"); 
    } 
    if (function.contains("**") | 
     function.contains("//") | 
     function.contains("--") | 
     function.contains("+*") | 
     function.contains("+/") | 
     function.contains("-*") | 
     function.contains("-/")) { 
     /* 
     * (-+ , +- , *- , *+ , /- , /+)> Those values are admitted 
     */ 
     throw new IllegalArgumentException("Operators are misused in the function"); 
    } 
    function = function.replace(" ", ""); 
    int position; 
    int operatorIndex = 0; 
    String currentOperator; 
    do { 
     currentOperator = operators.substring(operatorIndex,operatorIndex+1); 
     if (currentOperator.equals("*")) { 
      currentOperator+="/"; 
      operatorIndex++; 
     }else if (currentOperator.equals("+")) { 
      currentOperator+="-"; 
      operatorIndex++; 
     } 
     operatorIndex++; 
     position = 0; 
     while (position < function.length()) { 
      if ((position == 0 && !(""+function.charAt(position)).equals("-") && !(""+function.charAt(position)).equals("+") && operators.contains(""+function.charAt(position))) || 
       (position == function.length()-1 && operators.contains(""+function.charAt(position)))){ 
       throw new IllegalArgumentException("Operators are misused in the function"); 
      } 
      if (currentOperator.contains(function.substring(position, position+1)) & position != 0) { 
       int firstTermBeginIndex = position; 
       while (firstTermBeginIndex > 0) { 
        if ((alphanumeric.contains(""+function.charAt(firstTermBeginIndex))) & (operators.contains(""+function.charAt(firstTermBeginIndex-1)))){ 
         break; 
        } 
        firstTermBeginIndex--; 
       } 
       if (firstTermBeginIndex != 0 && (function.charAt(firstTermBeginIndex-1) == '-' | function.charAt(firstTermBeginIndex-1) == '+')) { 
        if (firstTermBeginIndex == 1) { 
         firstTermBeginIndex--; 
        }else if (operators.contains(""+(function.charAt(firstTermBeginIndex-2)))){ 
         firstTermBeginIndex--; 
        } 
       } 
       String firstTerm = function.substring(firstTermBeginIndex,position); 
       int secondTermLastIndex = position; 
       while (secondTermLastIndex < function.length()-1) { 
        if ((alphanumeric.contains(""+function.charAt(secondTermLastIndex))) & (operators.contains(""+function.charAt(secondTermLastIndex+1)))) { 
         break; 
        } 
        secondTermLastIndex++; 
       } 
       String secondTerm = function.substring(position+1,secondTermLastIndex+1); 
       double result; 
       switch (function.substring(position,position+1)) { 
        case "*": result = solveSingleValue(firstTerm,values)*solveSingleValue(secondTerm,values); break; 
        case "/": result = solveSingleValue(firstTerm,values)/solveSingleValue(secondTerm,values); break; 
        case "+": result = solveSingleValue(firstTerm,values)+solveSingleValue(secondTerm,values); break; 
        case "-": result = solveSingleValue(firstTerm,values)-solveSingleValue(secondTerm,values); break; 
        case "^": result = Math.pow(solveSingleValue(firstTerm,values),solveSingleValue(secondTerm,values)); break; 
        default: throw new IllegalArgumentException("Unknown operator: "+currentOperator); 
       } 
       String newAttribute = getNewKey(values); 
       values.put(newAttribute, result); 
       function = function.substring(0,firstTermBeginIndex)+newAttribute+function.substring(secondTermLastIndex+1,function.length()); 
       deleteValueIfPossible(firstTerm, values, motherFunction); 
       deleteValueIfPossible(secondTerm, values, motherFunction); 
       position = -1; 
      } 
      position++; 
     } 
    }while (operatorIndex < operators.length()); 
    return solveSingleValue(function, values); 
} 

private static double solveSingleValue (String singleValue, HashMap<String, Double> values) throws IllegalArgumentException{ 

    if (isDouble(singleValue)) { 
     return Double.parseDouble(singleValue); 
    }else if (firstContainsOnlySecond(singleValue, alphabetic)){ 
     return getValueFromVariable(singleValue, values); 
    }else if (firstContainsOnlySecond(singleValue, alphanumeric+"-+")) { 
     String[] composition = splitByLettersAndNumbers(singleValue); 
     if (composition.length != 2) { 
      throw new IllegalArgumentException("Wrong expression: "+singleValue); 
     }else { 
      if (composition[0].equals("-")) { 
       composition[0] = "-1"; 
      }else if (composition[1].equals("-")) { 
       composition[1] = "-1"; 
      }else if (composition[0].equals("+")) { 
       composition[0] = "+1"; 
      }else if (composition[1].equals("+")) { 
       composition[1] = "+1"; 
      } 
      if (isDouble(composition[0])) { 
       return Double.parseDouble(composition[0])*getValueFromVariable(composition[1], values); 
      }else if (isDouble(composition[1])){ 
       return Double.parseDouble(composition[1])*getValueFromVariable(composition[0], values); 
      }else { 
       throw new IllegalArgumentException("Wrong expression: "+singleValue); 
      } 
     } 
    }else { 
     throw new IllegalArgumentException("Wrong expression: "+singleValue); 
    } 
} 

private static double getValueFromVariable (String variable, HashMap<String, Double> values) throws IllegalArgumentException{ 

    Double val = values.get(variable); 
    if (val == null) { 
     throw new IllegalArgumentException("Unknown variable: "+variable); 
    }else { 
     return val; 
    } 
} 

/* 
* FunctionSolver help tools: 
* 
*/ 

private static final String alphabetic = "abcdefghilmnopqrstuvzwykxy"; 
private static final String numeric = "."; 
private static final String alphanumeric = alphabetic+numeric; 
private static final String operators = "^*/+-"; //--> Operators order in important! 

private static boolean firstContainsOnlySecond(String firstString, String secondString) { 

    for (int j = 0 ; j < firstString.length() ; j++) { 
     if (!secondString.contains(firstString.substring(j, j+1))) { 
      return false; 
     } 
    } 
    return true; 
} 

private static String getNewKey (HashMap<String, Double> hashMap) { 

    String alpha = "abcdefghilmnopqrstuvzyjkx"; 
    for (int j = 0 ; j < alpha.length() ; j++) { 
     String k = alpha.substring(j,j+1); 
     if (!hashMap.containsKey(k) & !Arrays.asList(usableMathMethods()).contains(k)) { 
      return k; 
     } 
    } 
    for (int j = 0 ; j < alpha.length() ; j++) { 
     for (int i = 0 ; i < alpha.length() ; i++) { 
      String k = alpha.substring(j,j+1)+alpha.substring(i,i+1); 
      if (!hashMap.containsKey(k) & !Arrays.asList(usableMathMethods()).contains(k)) { 
       return k; 
      } 
     } 
    } 
    throw new NullPointerException(); 
} 

public static String[] usableMathMethods() { 

    /* 
    * Only methods that: 
    * return a double type 
    * present one or two parameters (which are double type) 
    */ 

    Method[] mathMethods = Math.class.getDeclaredMethods(); 
    ArrayList<String> usableMethodsNames = new ArrayList<>(); 
    for (Method method : mathMethods) { 
     boolean usable = true; 
     int argumentsCounter = 0; 
     Class<?>[] methodParametersTypes = method.getParameterTypes(); 
     for (Class<?> parameter : methodParametersTypes) { 
      if (!parameter.getSimpleName().equalsIgnoreCase("double")) { 
       usable = false; 
       break; 
      }else { 
       argumentsCounter++; 
      } 
     } 
     if (!method.getReturnType().getSimpleName().toLowerCase().equals("double")) { 
      usable = false; 
     } 
     if (usable & argumentsCounter<=2) { 
      usableMethodsNames.add(method.getName()); 
     } 
    } 
    return usableMethodsNames.toArray(new String[usableMethodsNames.size()]); 
} 

private static boolean isDouble (String number) { 
    try { 
     Double.parseDouble(number); 
     return true; 
    }catch (Exception ex) { 
     return false; 
    } 
} 

private static String[] splitByLettersAndNumbers (String val) { 
    if (!firstContainsOnlySecond(val, alphanumeric+"+-")) { 
     throw new IllegalArgumentException("Wrong passed value: <<"+val+">>"); 
    } 
    ArrayList<String> response = new ArrayList<>(); 
    String searchingFor; 
    int lastIndex = 0; 
    if (firstContainsOnlySecond(""+val.charAt(0), numeric+"+-")) { 
     searchingFor = alphabetic; 
    }else { 
     searchingFor = numeric+"+-"; 
    } 
    for (int j = 0 ; j < val.length() ; j++) { 
     if (searchingFor.contains(val.charAt(j)+"")) { 
      response.add(val.substring(lastIndex, j)); 
      lastIndex = j; 
      if (searchingFor.equals(numeric+"+-")) { 
       searchingFor = alphabetic; 
      }else { 
       searchingFor = numeric+"+-"; 
      } 
     } 
    } 
    response.add(val.substring(lastIndex,val.length())); 
    return response.toArray(new String[response.size()]); 
} 

private static void deleteValueIfPossible (String val, HashMap<String, Double> values, String function) { 
    if (values.get(val) != null & function != null) { 
     if (!function.contains(val)) { 
      values.remove(val); 
     } 
    } 
} 

private static int contOccouranceIn (String howManyOfThatString, String inThatString) { 
    return inThatString.length() - inThatString.replace(howManyOfThatString, "").length(); 
} 
}