java কশন জাভা রেফারেন্স দ্বারা একটি স্ট্রিং পাস?




জাভা সুইং (12)

কী হচ্ছে তা হল রেফারেন্স মান দ্বারা পাস করা হয়, অর্থাত, রেফারেন্সের একটি অনুলিপি পাস করা হয়। রেফারেন্স দ্বারা জাভা তে কোন কিছুই প্রেরণ করা হয় না, এবং যেহেতু একটি স্ট্রিং অপরিবর্তনীয়, তাই অ্যাসাইনমেন্ট একটি নতুন স্ট্রিং বস্তু তৈরি করে যা রেফারেন্সের কপি এখন নির্দেশ করে। মূল রেফারেন্স এখনও খালি স্ট্রিং পয়েন্ট।

এটি কোনও বস্তুর জন্য একই রকম, অর্থাৎ এটি একটি পদ্ধতিতে একটি নতুন মানতে সেট করা। নীচের উদাহরণটি আরও স্পষ্টভাবে কী ঘটছে তা তোলে, তবে একটি স্ট্রিংকে সংযোজন করা সত্যিই একই জিনিস।

void foo( object o )
{
    o = new Object( );  // original reference still points to old value on the heap
}

আমি C নিম্নলিখিত নিম্নলিখিত ব্যবহার করা হয়:

void main() {
    String zText = "";
    fillString(zText);
    printf(zText);
}

void fillString(String zText) {
    zText += "foo";
}

এবং আউটপুট হয়:

foo

যাইহোক, জাভা, এই কাজ বলে মনে হচ্ছে না। আমি অনুমান করছি কারণ String বস্তুর প্রতিলিপি পরিবর্তে পরিবর্তিত হয় । আমি স্ট্রিং বস্তু ছিল, যা সবসময় রেফারেন্স দ্বারা গৃহীত হয়।

এখানে কি হচ্ছে?


স্ট্রিং জাভা মধ্যে অপরিবর্তনীয়। আপনি পরিবর্তন / পরিবর্তন করতে পারবেন না, একটি বিদ্যমান স্ট্রিং আক্ষরিক / বস্তু।

স্ট্রিং গুলি = "হ্যালো"; গুলি = S + "হাই";

এখানে পূর্ববর্তী রেফারেন্সটি নতুন রেফারেন্সের দ্বারা প্রতিস্থাপিত হয়েছে যা "হ্যালোহি" মানের দিকে নির্দেশ করে।

তবে, রূপান্তর আনয়ন করার জন্য আমাদের স্ট্রিংবিল্ডার এবং স্ট্রিংবফার রয়েছে।

স্ট্রিংবিল্ডার এস = নতুন স্ট্রিংবিল্ডার (); s.append ( "হাই");

এই একই refernce গুলি নতুন মান "হাই" যোগ করে। //


জাভাতে রেফারেন্স দ্বারা একটি বস্তু (স্ট্রিং সহ) পাস করার জন্য, আপনি এটি একটি পার্শ্ববর্তী অ্যাডাপ্টারের সদস্য হিসাবে পাস করতে পারেন। একটি জেনেরিক সঙ্গে একটি সমাধান এখানে:

import java.io.Serializable;

public class ByRef<T extends Object> implements Serializable
{
    private static final long serialVersionUID = 6310102145974374589L;

    T v;

    public ByRef(T v)
    {
        this.v = v;
    }

    public ByRef()
    {
        v = null;
    }

    public void set(T nv)
    {
        v = nv;
    }

    public T get()
    {
        return v;
    }

// ------------------------------------------------------------------

    static void fillString(ByRef<String> zText)
    {
        zText.set(zText.get() + "foo");
    }

    public static void main(String args[])
    {
        final ByRef<String> zText = new ByRef<String>(new String(""));
        fillString(zText);
        System.out.println(zText.get());
    }
}

স্ট্রিং জাভা একটি বিশেষ ক্লাস। এটি থ্রেড সেফ যার অর্থ "একবার স্ট্রিং ইনস্ট্যান্স তৈরি হয়, স্ট্রিং ইনস্ট্যান্সের সামগ্রী কখনই পরিবর্তিত হবে না"।

এখানে জন্য কি হচ্ছে

 zText += "foo";

প্রথমত, জাভা কম্পাইলারটি ZText স্ট্রিং ইনস্ট্যান্সের মান পাবে, তারপরে একটি নতুন স্ট্রিং ইনস্ট্যান্স তৈরি করবে যার মূল্য zText "foo" যুক্ত করে। তাই আপনি জানেন কেন zText পয়েন্ট পরিবর্তন করা হয় না। এটা সম্পূর্ণ একটি নতুন উদাহরণ। আসলে, এমনকি স্ট্রিং "foo" একটি নতুন স্ট্রিং উদাহরণ। সুতরাং, এই বিবৃতির জন্য, জাভা দুটি স্ট্রিং ইনস্ট্যান্স তৈরি করবে, একটি "foo", অন্যটি zText এর মান "foo" যুক্ত করবে। নিয়মটি সহজ: স্ট্রিং ইনস্ট্যান্সের মান কখনোই পরিবর্তিত হবে না।

মেথড ফিল্টারিংয়ের জন্য, আপনি স্ট্রিংবফারকে পরামিতি হিসেবে ব্যবহার করতে পারেন, অথবা আপনি এটির মতো এটি পরিবর্তন করতে পারেন:

String fillString(String zText) {
    return zText += "foo";
}

এই StringBuffer ব্যবহার করে কাজ করে

public class test {
 public static void main(String[] args) {
 StringBuffer zText = new StringBuffer("");
    fillString(zText);
    System.out.println(zText.toString());
 }
  static void fillString(StringBuffer zText) {
    zText .append("foo");
}
}

এমনকি ভাল StringBuilder ব্যবহার করুন

public class test {
 public static void main(String[] args) {
 StringBuilder zText = new StringBuilder("");
    fillString(zText);
    System.out.println(zText.toString());
 }
  static void fillString(StringBuilder zText) {
    zText .append("foo");
}
}

জাভা সমস্ত আর্গুমেন্ট মান দ্বারা পাস করা হয়। যখন আপনি একটি ফাংশনে একটি String পাস করেন, মানটি গৃহীত হয় একটি স্ট্রিং বস্তুর একটি রেফারেন্স, তবে আপনি সেই রেফারেন্সটি সংশোধন করতে পারবেন না এবং অন্তর্নিহিত স্ট্রিং বস্তু অপরিবর্তনীয়।

নিয়োগ

zText += foo;

সমতুল্য:

zText = new String(zText + "foo");

অর্থাৎ, এটি (স্থানীয়ভাবে) একটি নতুন রেফারেন্স হিসাবে পরামিতি zText পুনর্বিন্যাস করে, যা একটি নতুন মেমরি অবস্থানকে নির্দেশ করে, যা একটি নতুন String যা "foo" যুক্ত zText আসল সামগ্রী ধারণ করে।

মূল বস্তুটি সংশোধন করা হয় না এবং main() পদ্ধতির স্থানীয় পরিবর্তনশীল zText এখনও মূল (খালি) স্ট্রিংকে নির্দেশ করে।

class StringFiller {
  static void fillString(String zText) {
    zText += "foo";
    System.out.println("Local value: " + zText);
  }

  public static void main(String[] args) {
    String zText = "";
    System.out.println("Original value: " + zText);
    fillString(zText);
    System.out.println("Final value: " + zText);
  }
}

কপি করে প্রিন্ট:

Original value:
Local value: foo
Final value:

আপনি যদি স্ট্রিংটি সংশোধন করতে চান তবে আপনি StringBuilder ব্যবহার করতে পারেন অথবা অন্য কিছু ধারক (একটি অ্যারে বা একটি AtomicReference বা একটি কাস্টম কন্টেইনার ক্লাস) যা আপনাকে পয়েন্টার AtomicReference অতিরিক্ত স্তর দেয়। বিকল্পভাবে, শুধুমাত্র নতুন মান প্রদান করুন এবং এটি বরাদ্দ করুন:

class StringFiller2 {
  static String fillString(String zText) {
    zText += "foo";
    System.out.println("Local value: " + zText);
    return zText;
  }

  public static void main(String[] args) {
    String zText = "";
    System.out.println("Original value: " + zText);
    zText = fillString(zText);
    System.out.println("Final value: " + zText);
  }
}

কপি করে প্রিন্ট:

Original value:
Local value: foo
Final value: foo

সাধারণ ক্ষেত্রে এটি সম্ভবত সর্বাধিক জাভা-মত সমাধান - কার্যকর জাভা আইটেমটি দেখুন "অপেক্ষাকৃত অপেক্ষাকৃততা।"

উল্লেখ্য, যদিও, StringBuilder প্রায়ই আপনাকে ভাল পারফরম্যান্স প্রদান করবে - যদি আপনার প্রচুর StringBuilder বিশেষত একটি লুপের ভিতরে StringBuilder ব্যবহার StringBuilder

তবে পরিবর্তনযোগ্য StringBuilders পরিবর্তে StringBuilders Strings পাস করার চেষ্টা করুন - আপনার কোডটি সহজে পড়তে এবং আরও বেশি StringBuilders হতে পারে। আপনার প্যারামিটারগুলিকে final এবং আপনার আইডিই কনফিগার করার বিষয়ে আপনাকে সতর্ক করার জন্য বিবেচনা করুন যখন আপনি একটি নতুন মানের জন্য একটি পদ্ধতি পরামিতি পুনঃনির্মাণ করেন।


স্ট্রিং জাভা একটি অপরিবর্তনীয় বস্তু। আপনি যে কাজটি সম্পন্ন করার চেষ্টা করছেন সেটি করার জন্য আপনি স্ট্রিংবিল্ডার ক্লাস ব্যবহার করতে পারেন:

public static void main(String[] args)
{
    StringBuilder sb = new StringBuilder("hello, world!");
    System.out.println(sb);
    foo(sb);
    System.out.println(sb);

}

public static void foo(StringBuilder str)
{
    str.delete(0, str.length());
    str.append("String has been modified");
}

আরেকটি বিকল্প নিম্নরূপ একটি স্কোপ পরিবর্তনশীল (অত্যন্ত নিরুৎসাহিত) হিসাবে একটি স্ট্রিং সঙ্গে একটি ক্লাস তৈরি করা হয়:

class MyString
{
    public String value;
}

public static void main(String[] args)
{
    MyString ms = new MyString();
    ms.value = "Hello, World!";

}

public static void foo(MyString str)
{
    str.value = "String has been modified";
}

java.lang.String অপরিবর্তনীয়।

আমি ইউআরএল পেস্ট ঘৃণা করি তবে https://docs.oracle.com/javase/10/docs/api/java/lang/String.html আপনার জন্য জাভা-ল্যান্ডে পড়ার এবং বোঝার জন্য অপরিহার্য।


আপনার তিনটি বিকল্প আছে:

  1. স্ট্রিংবিল্ডার ব্যবহার করুন:

    StringBuilder zText = new StringBuilder ();
    void fillString(StringBuilder zText) { zText.append ("foo"); }
  2. একটি ধারক বর্গ তৈরি করুন এবং আপনার পদ্ধতিতে ধারক একটি উদাহরণ পাস:

    public class Container { public String data; }
    void fillString(Container c) { c.data += "foo"; }
  3. একটি অ্যারে তৈরি করুন:

    new String[] zText = new String[1];
    zText[0] = "";
    
    void fillString(String[] zText) { zText[0] += "foo"; }

কর্মক্ষমতা বিন্দু থেকে, স্ট্রিংবিল্ডার সাধারণত সেরা বিকল্প।


উত্তর সহজ। জাভা স্ট্রিং অপরিবর্তনীয়। অতএব এটি 'চূড়ান্ত' সংশোধনকারী (বা সি / সি ++ এ 'Const' ব্যবহার করে) পছন্দ করে। সুতরাং, একবার বরাদ্দ করা হলে, আপনি কীভাবে এটির মতো পরিবর্তন করতে পারবেন না।

আপনি কোন স্ট্রিং পয়েন্ট যা মান পরিবর্তন করতে পারেন, কিন্তু আপনি প্রকৃত মান পরিবর্তন করতে পারবেন না যা এই স্ট্রিংটি বর্তমানে নির্দেশ করছে।

অর্থাৎ। String s1 = "hey" । আপনি s1 = "woah" তৈরি করতে পারেন এবং এটি পুরোপুরি ঠিক আছে, তবে আপনি প্রকৃতপক্ষে স্ট্রিংটির অন্তর্নিহিত মানটি পরিবর্তন করতে পারবেন না (এই ক্ষেত্রে: "হেই") প্লাস ইক্যালস ইত্যাদি ব্যবহার করে তারপরে অন্য কিছু করার জন্য (অর্থাৎ s1 += " whatup != "hey whatup" )।

এটি করার জন্য, স্ট্রিংবিল্ডার বা স্ট্রিংবফার ক্লাসগুলি বা অন্যান্য পরিবর্তনযোগ্য কন্টেইনারগুলি ব্যবহার করুন, তারপর বস্তুটি আবার একটি স্ট্রিং রূপান্তর করতে .toString () কল করুন।

নোট: স্ট্রিংগুলিকে প্রায়ই হ্যাশ কী হিসাবে ব্যবহার করা হয়, যেহেতু তারা কেন অপরিবর্তনীয়।


স্ট্রিং জাভা immutable


জাভা কিছু রেফারেন্স দ্বারা গৃহীত হয় । সবকিছু মান দ্বারা পাস করা হয় । বস্তু রেফারেন্স মান দ্বারা পাস করা হয়। উপরন্তু স্ট্রিং অপরিবর্তনীয় । সুতরাং যখন আপনি পাস করা স্ট্রিং যুক্ত করবেন তখন আপনি একটি নতুন স্ট্রিং পাবেন। আপনি একটি রিটার্ন মান ব্যবহার করতে পারেন, অথবা পরিবর্তে একটি স্ট্রিংবফার পাস করতে পারেন।





pass-by-value