webForumDet fria alternativet

Datatypsoberoende metod

2 svar · 331 visningar · startad av Rex Nemo

Rex NemoMedlem sedan mars 200225 inlägg
#1

Hej!
Jag har en metod för att ta bort poster från en databas och den fungerar fint när den är definierad för en viss datatyp. För att inte behöva skapa en likadan metod för alla datatyper, så skulle jag vilja göra denna metod datatypsoberoende. Det är bara en del av programmet, som jag behöver ändra, men problemet är att jag inte vet hur jag ska göra.

Är det någon som har ett/flera förslag på hur jag kan gå tillväga?

Jag skulle vilja kunna anropa denna metod på följande sätt:

delete("DOUBLE_COL", "!=", 1.23);
delete("INTEGER_COL", "<", 100);
delete("LONG_COL", "<=", 10000);
delete("STRING_COL", "=", "Sträng");

MVH Rex

//public void delete(String column, String operator, Object value) throws IOException {	// funkar inte
public void delete(String column, String operator, int value) throws IOException {	// funkar utmärkt		
	table = new RandomAccessFile(tableFile, "rw");
	ArrayList result = new ArrayList();
	
	int numRows = this.getNumRows();
	int numCols = this.definition.getNumberOfColumns();
	String[] columnTypes = definition.getColumnTypes();
	long currentRecord = Header.DATA_START_POS;
	
	table.seek(Header.DATA_START_POS);
	
	for(int i = 0; i < numRows; i++) {
		Row row = new Row(this);			
		long lastRecord = Header.DATA_START_POS + ((numRows - 1) * definition.getRowLength());
		boolean found = false;
		
		for(int j = 0; j < numCols; j++) {				
			if(columnTypes[j].equals("Double")) {
				row.setDouble(j, table.readDouble());
			} else if(columnTypes[j].equals("Integer")) {
				row.setInt(j, table.readInt());
			} else if(columnTypes[j].equals("Long")) {
				row.setLong(j, table.readLong());
			} else if(columnTypes[j].equals("String")) {
				byte[] strArray = new byte[(int) definition.getColumnLength(j)];
				table.readFully(strArray);
				String str = new String(strArray);
				row.setString(j, str.trim());
			}
		}

//**************************************************
Det är den här delen, som ställer till det, eftersom den är definierad för int.
Hur kan jag göra den här delen datatypsoberoende?

		// Validera operator och jämför value och row värdet.			
		if(operator.equals("!=")) {		// Ej lika med
			if(value != row.getInt(column)) {
				found = true;
			}
		} else if(operator.equals("<")) {	// Mindre än
			if(value < row.getInt(column)) {
				found = true;
			}
		} else if(operator.equals("<=")) {	// Mindre än eller lika med
			if(value <= row.getInt(column)) {			
				found = true;
			}
		} else if(operator.equals("=")) {	// Lika med
			if(value == row.getInt(column)) {
				found = true;
			}
		} else if(operator.equals(">=")) {	// Större än eller lika med
			if(value >= row.getInt(column)) {
				found = true;
			}
		} else if(operator.equals(">")) {	// Större än
			if(value > row.getInt(column)) {
				found = true;
			}
		}
//**************************************************
		
		if(found) {
			if(currentRecord != lastRecord) {				
				table.seek(lastRecord);
				Row lastRow = new Row(this);

				for(int j = 0; j < numCols; j++) {
					if(columnTypes[j].equals("Double")) {
						lastRow.setDouble(j, table.readDouble());
					} else if(columnTypes[j].equals("Integer")) {
						lastRow.setInt(j, table.readInt());
					} else if(columnTypes[j].equals("Long")) {
						lastRow.setLong(j, table.readLong());
					} else if(columnTypes[j].equals("String")) {
						byte[] strArray = new byte[(int) definition.getColumnLength(j)];
						table.readFully(strArray);
						String str = new String(strArray);
						lastRow.setString(j, str);
					}
				}
				
				table.seek(currentRecord);

				for(int k = 0; k < lastRow.getNumberOfColumns(); k++) {
					if(columnTypes[k].equals("Double")) {
						table.writeDouble(lastRow.getDouble(k));
					} else if(columnTypes[k].equals("Integer")) {
						table.writeInt(lastRow.getInt(k));
					} else if(columnTypes[k].equals("Long")) {
						table.writeLong(lastRow.getLong(k));
					} else if(columnTypes[k].equals("String")) {
						table.writeBytes(lastRow.getString(k));
					}
				}
			}
			
			currentRecord = table.getFilePointer();
			numRows--;
			this.setNumRows(numRows);			
			table.setLength(Header.DATA_START_POS + (numRows * definition.getRowLength()));
		} else {
			currentRecord = table.getFilePointer();
		}
	}		
	table.close();
}
spangoMedlem sedan juni 20008 205 inlägg
#2

Du skickar in objekt rakt igenom (Double i stället för double, Integer i stället för int etc.), använder compareTo och equals för att testa värden, samt getObject i ResultSet för att läsa värdet. Eller, det är en kvalificerad gissning iaf :)

\r Sen skulle jag vilja tillägga att jag inte gillar din lösning för att kolla hur du ska jämföra (för det första är if-satser är av ondo, och för det andra är den inte typsäker). I Java 5 kan du använda en enum på ett rätt snyggt sätt för att lösa det:

enum ComparisonOperator {

  LESS () { boolean holdsFor(Object a, Object b){ return a.compareTo(b) < 0; } },
  EQUAL () { boolean holdsFor(Object a, Object b){ return a.compareTo(b) == 0; } },
  GREATER () { boolean holdsFor(Object a, Object b){ return LESS.holdsFor(b, a); },
  LESS_EQ () { boolean holdsFor(Object a, Object b){ return !GREATER.holdsFor(b, a); },
  NOT_EQUAL () { boolean holdsFor(Object a, Object b){ !EQUAL.holdsFor(a, b); } },
  GREATER_EQ () { boolean holdsFor(Object a, Object b){ return !LESS.holdsFor(b, a); };

  boolean holdsFor(Object a, Object b){ return false; }

}

// ...

  public void delete(String column, ComparisonOperator cmpOp, Object value) throws IOException {
    // ...
    if (cmpOp.holdsFor(row.getObject(column), value) {
      // värdet i raden uppfyller villkoret
    }
  }

// ...

delete("stringcol", ComparisonOperator.NOT_EQUAL, "Iä! Cthulhu f'taghn"); // alla rader som inte motsvarar strängen
delete("doublecol", ComparisonOperator.LESS, new Double(5)); // alla rader som är mindre än 5

(extremt otestat)

Rex NemoMedlem sedan mars 200225 inlägg
#3

Tack Spango för ett mycket bra svar! Jag håller med dig när det gäller if-satserna, men vad gör man om man inte vet bättre? :e

MVH Rex

132 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
129 ms — hämta tråd, inlägg och bilagor (db)