9
votes

Échangez deux cordes en Java, en les transmettant à une fonction utilitaire, mais sans retourner des objets ou en utilisant des cours d'emballage

J'essaie d'échanger deux cordes en Java. Je n'ai jamais vraiment compris "les chaînes sont immuables". Je le comprends en théorie, mais je ne l'ai jamais rencontré dans la pratique.

En outre, puisque la chaîne est un objet en Java et non un type primitif, je ne comprends pas pourquoi le code suivant imprime le même résultat deux fois, au lieu de Interchangeant les mots! p> xxx pré>

Je veux qu'il imprime p> xxx pré>

mais il s'agit d'impression p>

Hello World
Hello World


0 commentaires

10 Réponses :


15
votes

Je pensais que S1 et S2 sont des références et que les références doivent donc être échangées et que les nouveaux devraient pointer vers l'autre respectivement.

Oui. Localement à l'intérieur swap , c'est exactement ce qui se passe.

Toutefois, s1 et S2 sont copies des références passées dans la fonction, l'effet reste donc local. Notez que ce n'est pas les chaînes copiées (puisque chaîne est un type de référence). Mais les références sont copiées.

... et puisque les références de paramètres sont toujours copiées en Java, écrire un swap fonction selon vos spécifications est tout simplement possible.

Si vous rencontrez des problèmes de comprendre la différence, considérez ceci: vous souhaitez écrire une lettre à un ami afin de copier son adresse postale de votre carnet d'adresses sur une enveloppe. Par ce processus, vous n'avez certainement pas copié sa maison (la copie de toute une maison est un peu difficile dans la pratique) - vous avez seulement copié l'adresse.

Eh bien, une adresse se réfère à sa maison, donc c'est exactement comme une référence Java.


4 commentaires

Comment puis-je échanger deux cordes sans retourner des objets, en les transmettant à une autre fonction? N'est-il pas possible en Java?


Seulement maintenant, j'ai compris les "copies des références". Merci :)


@Senthil: Désolé, j'ai oublié de mentionner ça. Oui, écrire un tel Swap en Java est en effet impossible.


Je suis au courant du concept de références. Mais je ne suis pas au courant de la quantité de Java ne vous permet pas de programmer l'utilisation. Merci pour l'explication :)



3
votes

Fondamentalement, vous ne pouvez pas implémenter la méthode code> code> en Java.

La raison pour laquelle vous ne pouvez pas faire est que l'argument de Java a une sémantique d'argument passe-valeur. Donc, lorsque votre méthode attribue code> attribue S2 code> à S1 code> etc., il fonctionne entièrement sur les variables em> locales em> Code> S1 code> et S2 code> et non sur le S1 code> et S2 code> variables dans la méthode d'appel principale code >. P>

En revanche, si vous deviez implémenter la méthode code> Swap code> en C, il ressemblerait à ceci: P>

char *s1 = "Hello World";
char *s2 = "Goodbye World";
swap(&s1, &s2);


0 commentaires

1
votes

Les variables S1 et S2 de votre fonction Swap sont locales sur cette fonction.

Vous devez définir S1 et S2 en tant que variables privées pour votre classe ou renvoyer une gamme de chaînes de votre fonction.


0 commentaires

1
votes

Étant donné que Java utilise une valeur de réussite, la fonction d'échange que vous avez définie ne fait aucun type d'échange; Les pointeurs S1 et S2 sont échangés localement, mais le résultat du swap ne persiste pas. La chose la plus proche que vous puissiez réaliser est d'envelopper les éléments que vous souhaitez échanger dans une classe et de définir une méthode d'échange dans cette classe. Cela vous permettra d'échanger des données entre les instances de cette classe, bien qu'elle ne échange pas réellement les données sous-jacentes. À titre d'exemple de ceci:

  public class Swapper<T> {
      public Swapper(T obj) {
             data_ = obj;
      }
      public T get() { return data_; }
      public void set(T value) { data_ = value; }
      public void swap(Swapper<T> o) {
           T tmp = o.data_;
           o.data_ = data_;
           data_ = tmp;
      }
      private T data_ = null;
  }

  // .. Now you can do:
  Swapper<String> a = new Swapper("Hello");
  Swapper<String> b = new Swapper("World");
  // a.get().equals("Hello")
  a.swap(b); // now a.get().equals("World")


0 commentaires

2
votes

Il y avait Une question très similaire récemment à propos de l'échange de deux int. Et Ma réponse alors était à Utilisez Références atomiques :

public void swap(AtomicReference<String> a, AtomicReference<String> b){
    // update: look mom, no variables
    a.set(b.getAndSet(a.get()));
}


2 commentaires

La question dit, sans utiliser des cours d'emballage


@Newacct Oui, mais ce n'est pas possible dans Java (comme vous pouvez lire dans la réponse acceptée), donc je fournis une solution de contournement.



6
votes

Le code suivant est un nogo fort>, jamais implémenter ce modèle anti-modèle, ne jamais jamais modifier les internes finales privées sur des objets immuables. Ne me blâmez pas pour montrer ce piratage, blâmer le JVM d'Oracle pour ne pas le refuser.

Mais, si un jour vous trouvez du code où cela fonctionne: P>

 private void swap(String a, String b) {
   try {
     Field value = String.class.get("value");
     value.setAccessible(true);    // this should be forbidden!!

     char[] temp = value.get(a);
     value.set(a, value.get(b));
     value.set(b, temp);           // Aaargh, please forgive me
   } catch(Exception e) {
     e.printStackTrace(e);
   }
 }


1 commentaires

Cela ne échange pas les objets. Il utilise simplement le contenu des objets



2
votes

Java String code> s sont implémentés avec des références, vous devez donc échanger leurs références.

World Hello


0 commentaires

1
votes
String s1 = "Hello";
String s2 = "World";
    s1=s1+" "+s2;
s2=s1.split(" ")[0];
s1=s1.split(" ")[1];
System.out.println(s1 + " " + s2);

0 commentaires

0
votes

En utilisant StringBufferreader code> et StringBuilder code> Ceci peut être résolu. Au 1er, obtenez les valeurs de l'utilisateur, puis divisez-les et rangez-les en tableau. Exécutez la boucle pour l'ordre inverse de sorte que la dernière chaîne soit ajoutée et affichée 1er le premier affichera en dernier. Entrée: Bonjour World Sortie:

import java.io.*;
import java.util.*;
import java.lang.*;
public class Solution {
  public static void main(String[] args) {
    try {
      int s,i,j;
      StringBuilder str = new StringBuilder();
      String st,t;
      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
      t = br.readLine();
      s = Integer.parseInt(t);
      for (i = 0; i < s; i++) {
        st=br.readLine();
        String st1[]=st.split("\\s+");
        // System.out.println("l="+st1.length);
        for (j = st1.length - 1; j >= 0; j--) {
          str.append(st1[j] + " ");
        }
        System.out.println(str);
        str.setLength(0);
      }
    } catch (Exception e) {
      System.out.println(e);
    }
  }
}


0 commentaires

0
votes

Java passe l'adresse des objets dans la mémoire aux fonctions. Ensuite, une variable locale dans la fonction contient cette adresse. Il n'y a aucune raison de modifier l'objet d'origine si vous attribuez une nouvelle adresse (un autre objet) à ces variables locales.

Cependant, des modifications apportées à les champs de l'objet d'origine, avec l'adresse en main, sont appliquées. (Relation à . Opérateur en C / C ++)

Ce lien peut également aider.


0 commentaires