Avatar billede jespersahner Nybegynder
17. januar 2005 - 13:07 Der er 18 kommentarer og
1 løsning

StringBuffer med fixed length

Jeg ønsker at oprette en klasse med alle de samme egenskaber som StringBuffer, dog skal objekter altid have fixed length.

Idet StringBuffer er erklæret final, kan jeg ikke arve, så hvad gør jeg her?

(ideen med fixed length er i forbindelse med skrivning til fil)
Avatar billede kalp Novice
17. januar 2005 - 13:12 #1
lav et lille java program.. får det til at lave en exception.. følge linjen og du kommer ind i sourcen til StringBuffer hehe kopi and paste.. ret den til.. hvis du kan!
Avatar billede arne_v Ekspert
17. januar 2005 - 13:17 #2
Det bliver jo nok ikke alle de samme egenskaber.

append giver vel ingen mening for dit objekt.

Tast din klasse ind manuelt og vurder om metoden giver mening for hver
metode du taster ind.

Du kan lade din klasse indeholde en StringBuffer og bruge den til selve
storage.

Hvis du har en fleksibel moral kan du hapse StringBuffer fra src.jar og
hacke den.
Avatar billede jespersahner Nybegynder
17. januar 2005 - 13:57 #3
-> arne_v: Det er selvfølgelig en fremgangsmåde, men jeg undrer mig måske over, at StringBuffer er final, når nu arv er en naturlig ting i Java.

Men ellers kan jeg måske skrive en klasse X, der har en StringBuffer s som element og så lade mine metoder i X virke på s:

Class X {
    private StringBuffer s;
    X(StringBuffer s) {
        this.s=s;
    }
    // Metoden reverse:
    StringBuffer reverse() {
        return s.reverse();
    }
}
Avatar billede arne_v Ekspert
17. januar 2005 - 13:59 #4
Det var det jeg snakkede om med:

"Du kan lade din klasse indeholde en StringBuffer og bruge den til selve
storage."
Avatar billede arne_v Ekspert
17. januar 2005 - 14:03 #5
Med hensyn til arv så:

1)  Man kan komme ganske frygteligt galt af sted med at arve fra klasser
    som ikke er tiltænkt at skulle arve fra p.g.a. utilsigtet interaktion
    mellem implementationen i den oprindelige klasse og koden i den nye
    klasse

2)  Jeg mener at Gosling ("opfinderen" af Java) blev spurgt hvilken feature
    i Java han fortrød mest og svaret var: extends. 50% vittigt + 50% dybt
    seriøst.
Avatar billede jespersahner Nybegynder
17. januar 2005 - 14:13 #6
-> arne_v: Ja, ok.

Faktisk undrer jeg mig lidt over, at f.eks. metoden substring() i StringBuffer-klassen returnerer en String og ikke en StringBuffer. Betyder det ikke, at der oprettes et nyt String-objekt ved hvert kald af substring()? (og dermed måske et hastighedsproblem ved mange gentagelser)
Avatar billede arne_v Ekspert
17. januar 2005 - 14:19 #7
Det er vel ikke billigere at oprette et StringBuffer object ved hvert kald til
substring ??
Avatar billede jespersahner Nybegynder
17. januar 2005 - 18:07 #8
-> arne_v: Nej, men jeg forestiller mig at oprette en StringBuffer en gang for alle, hvorefter jeg genbruger denne løbende. Det er noget med en løkke, hvor jeg skriver til en fil, og i den forbindelse er jeg altid lidt bange for "new". Det er vel andet lige billigere at referere til samme StringBuffer hver gang i forhold til at oprette en ny ved hvert gennemløb.
Avatar billede arne_v Ekspert
17. januar 2005 - 18:41 #9
Det kan du måske godt spare en lille smule ved.

Men en substring skal stadigvæk returnere "noget".
Avatar billede jespersahner Nybegynder
17. januar 2005 - 20:18 #10
-> arne_v: Jo, men hvorfor returnerer den ikke bare en StringBuffer igen, kunne man spørge? Som jeg læser API'en, returneres en new String.
Avatar billede arne_v Ekspert
17. januar 2005 - 20:22 #11
Det koster mindst lige så meget at returnere en StringBuffer - formentligt mere.

Med stor sandsynelighed skal den ikke ændre men appendes til noget andet og så
er en String lige så god.

Så en eller anden hos SUN for mange år siden valgte String.
Avatar billede jespersahner Nybegynder
17. januar 2005 - 20:54 #12
-> arne_v: Vel ikke helt, hvis resultatet returneres i samme reference, således at der ikke oprettes et nyt objekt ved hvert gennemløb. Dette kan man med StringBuffer men ikke med String, som skal oprettes ny hver gang, da den er uforanderlig.
Avatar billede arne_v Ekspert
17. januar 2005 - 20:57 #13
Om det er:

x = x.substring(2,4);

eller

y = x.substring(2,4);

har ikke nogen effekt på hvad substring gør.

Den eneste måde hvorpå substring kunne undlade at create et nyt objekt
var hvis den smed alt andet en substring væk i sig selv. Og det er da en ret grim
side effect.
Avatar billede jespersahner Nybegynder
18. januar 2005 - 09:19 #14
-> arne_v: Jeg tror måske, at vi snakker lidt forbi hinanden.

Min pointe er blot, at for så vidt der returneres en String fra substring()-metoden, vil denne altid være et nyt objekt, da String er uforanderlig. Dette er helt specielt for String's. For så vidt der blev returneret en StringBuffer i stedet, ville der ikke være behov for at danne et nyt objekt hver gang, og resultatet kunne lagres i et allerede eksisterende objekt. Ved mange gennemløb forestiller jeg mig, at det er relativt dyrt at returnere en String i forhold til en StringBuffer.
Avatar billede arne_v Ekspert
18. januar 2005 - 14:14 #15
Jo der ville stadig vær ebehov for at lave et nyt objekt.

Fordi hvis du forsøgte at lave noget som:

public class SpecialStringBuffer {
    private StringBuffer str;
    private StringBuffer substr;
    public SpecialStringBuffer(String s) {
        str = new StringBuffer(s);
        substr = new StringBuffer();
    }
    public StringBuffer substring(int ix1, int ix2) {
        substr.setLength(ix2 - ix1);
        for(int i = ix1; i < ix2; i++) {
            substr.setCharAt(i - ix1, str.charAt(i));
        }
        return substr;
    }
}

så ville der igen være side effects.

        SpecialStringBuffer ssb = new SpecialStringBuffer("ABCD");
        StringBuffer firsthalf = ssb.substring(0, 2);
        StringBuffer lasthalf = ssb.substring(2, 4);
        System.out.println(firsthalf + " " + lasthalf);

udskriver:

CD CD

hvilket nok ikke ret mange vil betragte som logisk.
Avatar billede jespersahner Nybegynder
19. januar 2005 - 12:44 #16
->arne_v: For så vidt enig. Dette vil være tilfældet, når man genbruger samme objekt, som du gør i eksemplet. Referencerne 'firsthalf' og 'lasthalf' peger på samme objekt, og ændringen vedr. lasthalf vil således også påvirke firsthalf, jf.:


        SpecialStringBuffer ssb = new SpecialStringBuffer("ABCD");
        StringBuffer firsthalf = ssb.substring(0, 2);
        System.out.println(firsthalf);
        StringBuffer lasthalf = ssb.substring(2, 4);
        System.out.println(firsthalf + " " + lasthalf);

- som giver:
AB
CD CD

Men konstruktionen er slet ikke tosset, hvis man f.eks. skal skrive til en fil. I denne situation er genbrug af objektet oplagt, idet "indholdet af" objektet løbende skrives ud til filen, hvorefter det er klar til genbrug osv. Her giver det god mening med genbrug, så man sparer tid med at oprette et nyt objekt ved hvert gennemløb. Denne mulighed har man imidlertid ikke med String, som oprettes på ny hver gang, derfor min bemærkning omkring returnering af StringBuffer i stedet.

Hvis "method overloading" på en eller anden måde inkluderede retur-objektet, ville man kunne operere med samme metode-kald men forskellige retur-objekter, dvs. substring() kunne returnere en String hhv. en StringBuffer afhængig af anvendelse. Bare en løs tanke.
Avatar billede arne_v Ekspert
19. januar 2005 - 21:34 #17
Tjo, men construction + destruction af 1 objekt er ingenting sammenlignet med en IO.
Avatar billede jespersahner Nybegynder
24. januar 2005 - 10:09 #18
->arne_v: Smid lige et svar
Avatar billede arne_v Ekspert
24. januar 2005 - 10:14 #19
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester