# Zeile auf existenz von String prüfen.



## RawBit (1. Dez 2006)

soo ich wieder ne.. 

wie kann ich am besten (sprich unter so wenig CPU-Belastung wie möglich) die Zeile in einer jtextarea in der sich der caret befindet auf die existenz einer zeichenkette überprüfen

dabei is wichtig dass nur die zeile durchsucht wird in der der caret sitzt 

dankee


----------



## André Uhres (1. Dez 2006)

Schau dir mal dies an:

JTextComponent#getCaretPosition
JTextArea#getLineOfOffset
JTextArea#getLineStartOffset
JTextArea#getLineEndOffset
JTextComponent#getText
String#contains


----------



## RawBit (1. Dez 2006)

also von einer methode contains in string hab ich noch nix gehört


----------



## Wildcard (1. Dez 2006)

Ich schon


----------



## RawBit (1. Dez 2006)

also in der api steht nix


----------



## Wildcard (1. Dez 2006)

http://java.sun.com/j2se/1.5.0/docs/api/java/lang/String.html#contains(java.lang.CharSequence)


----------



## RawBit (1. Dez 2006)

aja jetzt seh ichs auch, kenn ich trotzdem nich


----------



## RawBit (2. Dez 2006)

ok ich hab keine ahnung wie ich das mit diesen komischen methoden getLine...Offset() machen soll...

kann mir mal wer helfen


----------



## André Uhres (2. Dez 2006)

```
lineNumber =  textarea.getLineOfOffset(textarea.getCaretPosition());
            int lineStart = textarea.getLineStartOffset(lineNumber);
            int lineEnd = textarea.getLineEndOffset(lineNumber);
```


----------



## RawBit (2. Dez 2006)

hmm ok danke ich probier das mal


----------



## byte (2. Dez 2006)

Wenn Du so ne Frage schon nicht im Anfängerforum stellst, müssen diese Antworten auch ausreichend zur Problemlösung sein. :bae:


----------



## RawBit (2. Dez 2006)

so mein script geht, dankee

```
public boolean containLineString(String text, JTextArea comp) {
    try {
      int line = comp.getLineOfOffset(comp.getCaretPosition());
      int a = comp.getLineStartOffset(line);
      int b = comp.getLineEndOffset(line);
      if(comp.getText().indexOf(text, a) < b && comp.getText().indexOf(text, a)!=-1)
        return true;
      return false;
    } catch( BadLocationException e) { System.err.println("ERROR!!!"); }
    return false;
  }
```

schau ich etwa aus wie ein anfäger  

nur machmal is java für nen php-programmierer etwas ... abstrakt  generell mein ich


----------



## Leroy42 (2. Dez 2006)

Hackl hat gesagt.:
			
		

> aja jetzt seh ichs auch, kenn ich trotzdem nich



Meine Ur-Oma kennt auch keine Telefone ohne Kabel. 

Ergo: Sowatt jibbet nich!


----------



## miketech (2. Dez 2006)

Hi,

Du wolltest doch eine möglichst effiziente Lösung, oder? 


```
if(comp.getText().indexOf(text, a) < b && comp.getText().indexOf(text, a)!=-1)
```

Was Du hier schonmal machst ist zweimal die Methode "indexOf" aufzurufen.

Stell Dir einen Text vor, bei dem das gesuchte Wort erst weit hinter der Position "a" vorkommt. Da kann es sein, dass er ganz schön lange sucht. Du willst ja nur den Text in dieser einen Zeile untersuchen.

Schau Dir daher mal die Methode an:


```
public String getText(int offs, int len)
```

Hab das nie probiert, aber laut Doku sollte sie Dir den Text von offs bis offs + len liefern.

Das sollte dann so in der Art bei Dir gehen:


```
String line = comp.getText(a, b-a);
   if (line.indexOf(text) != -1) {
      ...
   }
```

Dann wird wirklich nur die eine Zeile untersucht.

Gruß

Mike


----------



## SlaterB (2. Dez 2006)

naja, vielleicht ist die Suche sehr viel schneller als einen Teilstring zu bilden?
möchte ich nicht propagieren, aber das Gegenteil würde ich auch nicht sofort behaupten 
oder hast du Erfahrungen?

zweimal zu suchen ist in jedem Fall unnötig, das stimmt


----------



## miketech (2. Dez 2006)

Hi,

also Erfahrungen hab ich keine, weil ich Swing nur einmal genutzt habe. Aber ich würde es mal so sehen:

Im Folgenden sei das ursprüngliche Verfahren Nummer (1). Das von mir vorgestellte sei (2).

Man muss eh erstmal zur Position a. Das ist bei beiden Verfahren gleich. Dann müssen beide mindestens bis zu b.

Während er bei (1) nun einen Aufwand von X hat, um bis b nach dem String zu suchen, wird die Variante (2) einen Aufwand Y haben, um bis zu dem Punkt zu wandern. Suche erfolgt keine. Stattdessen wird ein String erzeugt. Daher kann man nicht pauschal Y < X sagen.

Nun muss das Verfahren (2) noch den String suchen. Hat also den Aufwand Y + X.

Das Verfahren (1) sucht nun aber noch weiter mit dem Aufwand Z.

Y + X < X + Z

gilt also, wenn Z größer als Y ist. Und bei einem sehr langen Text kann es schnell vorkommen, dass der Aufwand einen Text sequentiell zu durchsuchen größer ist, als einen String anzulegen.

Hierbei ist mit Aufwand CPU-Aufwand gemeint. 

Fazit: (2) lohnt sich, wenn man sich nicht unbedingt weit am Ende des Textes befindet, zumindest bzgl. CPU.

(1) lohnt sich, wenn die Texte kurz sind und man weniger Speicher verbrauchen will.


So und nun kommt noch die VM mit ihren Eigenschaften ins Spiel und würfelt vielleicht wieder alles durcheinander  Ich halte meine Variante dennoch für günstiger 

Gruß

Mike


----------



## RawBit (2. Dez 2006)

naja es geht und es läuft sehr flüssig das reicht mir


----------



## SlaterB (2. Dez 2006)

ist ja allgemein eine interessante Sache,
also noch ein kleiner Test dazu

schon bei 3 Zeilen (160 Zeichen) ist es in diesem Beispiel günstiger, 
nur die letzten 60 Zeichen zu durchsuchen als den ganzen String,

mächtig langsam diese indexOf-Suche
bzw. beruhigend, dass die Stringerzeugung nicht allzu lange dauert




```
import javax.swing.JTextArea;

public class Test {

	public static void main(String[] args) throws Exception {
		JTextArea comp = new JTextArea();

		for (int i = 0; i < 3; i++) {
			comp.append(
				"dfhsödhdls sjkhh3498z d98cx9x8cvcz v98xc7  98cxv98x\n");
		}
		comp.append("KKKdsfsd\n");

		String line = comp.getText();
		int a = line.length() - 60;
		int b = line.length() - 2;
		System.out.println("Start: " + line.length());
		long time = System.currentTimeMillis();
		for (int i = 0; i < 800000; i++) {
		//	line = comp.getText(a, b - a);
			if (line.indexOf("KKK") != -1) {
			}
		}

		System.out.println("Time: " + (System.currentTimeMillis() - time));

	}

	
}
```


----------



## miketech (3. Dez 2006)

Nice! Danke für den Test.

Gruß

Mike


----------



## RawBit (3. Dez 2006)

nicht schlecht


----------

