অপরিবর্তনীয় বলতে কী বোঝায়?


400

এটি কখনও জিজ্ঞাসা করা মূ .় প্রশ্ন হতে পারে তবে আমি মনে করি এটি জাভা নবাগতের পক্ষে যথেষ্ট বিভ্রান্তিকর।

  1. কেউ কি অপরিবর্তনীয় বলতে কী বোঝাতে পারে ?
  2. কেন Stringঅপরিবর্তনীয়?
  3. অপরিবর্তনীয় বস্তুর সুবিধা / অসুবিধাগুলি কী কী?
  4. StringBuilderস্ট্রিং এবং ভাইস-শ্লোকের চেয়ে কোনও পরিবর্তনীয় বস্তুর কেন পছন্দ করা উচিত ?

একটি দুর্দান্ত উদাহরণ (জাভাতে) সত্যিই প্রশংসা করা হবে।


73
দেখুন, এটি এমন বোবা প্রশ্ন ছিল না। আপনি জিজ্ঞাসা খুশি!
ডক

2
যাইহোক, আমি মনে করি না যে এটি কখনও দ্বন্দ্বজনক প্রশ্ন :) আমি মনে করি এটি বুঝতে একটি খুব গুরুত্বপূর্ণ ধারণা
জেসন কোকো

1
আপনি যখন স্ট্রিংবিল্ডার বলেছিলেন, আপনি কি মিউটেবল ক্লাস স্ট্রিংবফার বলতে চাইছেন না? স্ট্রিং এবং স্ট্রিংবুফারের চেয়ে ফাংশনে স্ট্রিং এবং স্ট্রিংবফার একই রকম। স্ট্রিংবাফার কার্যকরভাবে একটি পরিবর্তনীয় স্ট্রিং।
ডেরেক মাহর

3
আমি কি সুপারিশ করতে পারি যে আমরা এই প্রশ্নটিকে "শিক্ষানবিশ" ট্যাগটি যুক্ত করব যাতে জাভাতে নতুন প্রোগ্রামাররা এটি অন্যান্য সূচক প্রশ্নের সন্ধানে খুঁজে পেতে পারেন?
ডেরেক মাহর

উত্তর:


268

অপরিবর্তনীয় এর অর্থ হ'ল একবার যখন কোনও বস্তুর জন্য কনস্ট্রাক্টর সম্পাদন সম্পন্ন করে that দৃষ্টান্তটি পরিবর্তন করা যায় না।

এটি দরকারী কারণ এর অর্থ আপনি অন্য কেউ এর বিষয়বস্তু পরিবর্তন করতে যাবেন এমন ভেবে উদ্বেগ ছাড়াই আপনি চারপাশের অবজেক্টের রেফারেন্সগুলি পাস করতে পারবেন। বিশেষত চুক্তির সাথে ডিল করার সময় কোনও জিনিসই লক করার সমস্যা থাকে না যা কখনই বদলে না

যেমন

class Foo
{
     private final String myvar;

     public Foo(final String initialValue)
     {
         this.myvar = initialValue;
     }

     public String getValue()
     {
         return this.myvar;
     }
}

Fooকলারটিকে getValue()স্ট্রিংয়ের পাঠ্যটি পরিবর্তিত করতে পারে এমন চিন্তা করার দরকার নেই ।

আপনি যদি একই ধরণের ক্লাসটি কল্পনা করেন Fooতবে সদস্য হিসাবে StringBuilderবরং তার পরিবর্তে String, আপনি দেখতে পাচ্ছেন যে একজন কলকারী কোনও ঘটনার বৈশিষ্ট্যটি getValue()পরিবর্তন করতে সক্ষম হবেন ।StringBuilderFoo

এছাড়াও বিভিন্ন ধরণের অপরিবর্তনীয়তা থেকে আপনি সতর্ক হতে পারেন: এরিক লিপার্ট এই সম্পর্কে একটি ব্লগ নিবন্ধ লিখেছিলেন । মূলত আপনার কাছে এমন অবজেক্ট থাকতে পারে যার ইন্টারফেসটি অপরিবর্তনীয় তবে পর্দার আড়ালে প্রকৃত পরিবর্তনযোগ্য ব্যক্তিগত রাষ্ট্র (এবং তাই থ্রেডগুলির মধ্যে নিরাপদে ভাগ করা যায় না)।


3
আমি মনে করি আপনার কমপক্ষে একবার মূল্য নির্ধারণের জন্য একটি আরগ কনস্ট্রাক্টর যুক্ত করা উচিত। সত্যিকারের পরিবর্তনের কোনও মূল্য নেই বলে বর্তমান কোডের বিন্দুটি পরিষ্কার নয়।
জর্জি বলিবা

4
আপনার ক্ষেত্রটি পাঠযোগ্যভাবে করা উচিত। এটি একেবারে স্পষ্ট করে তোলে যে ক্ষেত্রটি অপরিবর্তনীয়। এখনই এটি কনভেনশন দ্বারা পরিবর্তনযোগ্য
জেয়ার্ডপাড়

7
সত্যিকারের অপরিবর্তনীয় হওয়ার জন্য মাইভার সদস্যটি চূড়ান্ত হওয়া উচিত।
ল্যাজ

13
আপনি সঠিক যে MyVar ফু এর বাইরে অ্যাক্সেসযোগ্য নয়। যাইহোক, চূড়ান্ত উপস্থিতি যে কোনও ব্যক্তিকে ইঙ্গিত করে যা ভবিষ্যতে শ্রেণিটি সংশোধন করতে পারে যে এর মান পরিবর্তন করার জন্য নয়। আমি এইরকম পরিস্থিতিতে যথাসম্ভব সুস্পষ্ট হওয়ার পক্ষে থাকি।
ল্যাজ

2
কীভাবে "কেবলমাত্র চূড়ান্ত কীওয়ার্ড ব্যবহার করে রেফারেন্সের ধরণগুলি অপরিবর্তনীয় করা যায় না final চূড়ান্ত কেবল পুনরায় নিয়োগকে বাধা দেয়" " থেকে en.wikipedia.org/wiki/Immutable_object
Yousha Aleayoub

81

অপরিবর্তনীয় বস্তু এমন একটি বস্তু যেখানে অভ্যন্তরীণ ক্ষেত্রগুলি (বা কমপক্ষে সমস্ত অভ্যন্তরীণ ক্ষেত্রগুলি যা এর বাহ্যিক আচরণকে প্রভাবিত করে) পরিবর্তন করা যায় না।

পরিবর্তনযোগ্য স্ট্রিংগুলির অনেক সুবিধা রয়েছে:

সম্পাদনা: নিম্নলিখিত ক্রিয়াকলাপটি গ্রহণ করুন:

String substring = fullstring.substring(x,y);

সাবস্ট্রিং () পদ্ধতির অন্তর্নিহিত সি সম্ভবত এমন কিছু:

// Assume string is stored like this:
struct String { char* characters; unsigned int length; };

// Passing pointers because Java is pass-by-reference
struct String* substring(struct String* in, unsigned int begin, unsigned int end)
{
    struct String* out = malloc(sizeof(struct String));
    out->characters = in->characters + begin;
    out->length = end - begin;
    return out;
}

নোট করুন যে কোনও একটি চরিত্রই অনুলিপি করতে হবে না! যদি স্ট্রিং অবজেক্টটি পরিবর্তনীয় হয় (অক্ষরগুলি পরে পরিবর্তন হতে পারে) তবে আপনাকে সমস্ত অক্ষর অনুলিপি করতে হবে, অন্যথায় স্ট্রিংয়ের অক্ষরে পরিবর্তনগুলি অন্য স্ট্রিংয়ের পরে প্রতিফলিত হবে।

Concurrency: যদি একটি অপরিবর্তনীয় বস্তুর অভ্যন্তরীণ গঠন বৈধ, এটা সবসময় কার্যকর থাকবে। বিভিন্ন থ্রেড যে অবজেক্টের মধ্যে একটি অবৈধ অবস্থা তৈরি করতে পারে এমন কোনও সুযোগ নেই। অতএব, অপরিবর্তনীয় জিনিসগুলি থ্রেড নিরাপদ

আবর্জনা সংগ্রহ: আবর্জনা সংগ্রহকারীদের পক্ষে অপরিবর্তনীয় বস্তু সম্পর্কে যৌক্তিক সিদ্ধান্ত নেওয়া আরও সহজ।

যাইহোক, অপরিবর্তনীয়তার জন্য ডাউনসাইডগুলিও রয়েছে:

পারফরম্যান্স: দাঁড়াও, আমি ভেবেছিলাম আপনি বলেছিলেন পারফরম্যান্স হ'ল অপরিবর্তনীয়তার sideর্ধ্বমুখী! ঠিক আছে, এটি কখনও কখনও হয়, তবে সবসময় হয় না। নিম্নলিখিত কোড নিন:

foo = foo.substring(0,4) + "a" + foo.substring(5);  // foo is a String
bar.replace(4,5,"a"); // bar is a StringBuilder

দুটি রেখা উভয়ই "a" অক্ষর দিয়ে চতুর্থ অক্ষরকে প্রতিস্থাপন করে। কোডের দ্বিতীয় ভাগটি কেবল বেশি পঠনযোগ্য নয়, এটি আরও দ্রুত। Foo এর জন্য আপনাকে অন্তর্নিহিত কোডটি কীভাবে করতে হবে তা দেখুন। সাবস্ট্রিংগুলি সহজ, তবে এখন যেহেতু পাঁচটি স্পেসে ইতিমধ্যে একটি চরিত্র রয়েছে এবং অন্য কোনও কিছু ফুকে রেফারেন্স দিচ্ছে, আপনি কেবল এটি পরিবর্তন করতে পারবেন না; আপনাকে পুরো স্ট্রিংটি অনুলিপি করতে হবে (অবশ্যই এই কার্যকারিতাটির কিছুটি আসল অন্তর্নিহিত সিতে ফাংশনগুলিতে বিমূর্ত করা হয়েছে, তবে এখানে বিন্দুটি কোডটি দেখানো যা সমস্ত এক জায়গায় কার্যকর করা হয়)।

struct String* concatenate(struct String* first, struct String* second)
{
    struct String* new = malloc(sizeof(struct String));
    new->length = first->length + second->length;

    new->characters = malloc(new->length);

    int i;

    for(i = 0; i < first->length; i++)
        new->characters[i] = first->characters[i];

    for(; i - first->length < second->length; i++)
        new->characters[i] = second->characters[i - first->length];

    return new;
}

// The code that executes
struct String* astring;
char a = 'a';
astring->characters = &a;
astring->length = 1;
foo = concatenate(concatenate(slice(foo,0,4),astring),slice(foo,5,foo->length));

নোট করুন যে সংযুক্তিকে দ্বিগুণ বলা হয় যার অর্থ পুরো স্ট্রিংটি লুপ করা উচিত! barঅপারেশনের জন্য এটি সি কোডের সাথে তুলনা করুন :

bar->characters[4] = 'a';

পরিবর্তনীয় স্ট্রিং অপারেশন স্পষ্টতই অনেক দ্রুত।

উপসংহারে: বেশিরভাগ ক্ষেত্রে, আপনি একটি পরিবর্তনীয় স্ট্রিং চান। তবে আপনাকে যদি স্ট্রিংয়ের মধ্যে অনেকগুলি সংযোজন এবং সন্নিবেশ করানোর দরকার হয়, আপনার গতির জন্য পরিবর্তনের প্রয়োজন। আপনি যদি এটির সাথে একযোগে সুরক্ষা এবং আবর্জনা সংগ্রহের সুবিধাগুলি চান তবে আপনার পরিবর্তনযোগ্য অবজেক্টগুলিকে কোনও পদ্ধতিতে স্থানীয় রাখতে হবে:

// This will have awful performance if you don't use mutable strings
String join(String[] strings, String separator)
{
    StringBuilder mutable;
    boolean first = true;

    for(int i = 0; i < strings.length; i++)
    {
        if(!first) first = false;
        else mutable.append(separator);

        mutable.append(strings[i]);
    }

    return mutable.toString();
}

যেহেতু mutableঅবজেক্টটি স্থানীয় রেফারেন্স, তাই আপনাকে সম্মতি সুরক্ষার বিষয়ে চিন্তা করতে হবে না (কেবলমাত্র একটি থ্রেডই এটি স্পর্শ করে)। এবং যেহেতু এটি অন্য কোথাও উল্লেখ করা হয়নি, এটি কেবল স্ট্যাকের জন্য বরাদ্দ করা হয়েছে, সুতরাং এটি ফাংশন কল শেষ হওয়ার সাথে সাথেই এটি বিচ্ছিন্ন করা হয়েছে (আপনাকে আবর্জনা সংগ্রহের বিষয়ে চিন্তা করতে হবে না)। এবং আপনি উভয় পরিবর্তন এবং অপরিবর্তনীয়তার সমস্ত কার্যকারিতা সুবিধা পান।


4
দুর্দান্ত পড়া! আমি কেবল একটি জিনিস মনে করি এটি হওয়া উচিত (প্রথম) এবং না হলে (! প্রথম)
সিদ্ধার্থ

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

7
Passing pointers because Java is pass-by-referenceজাভা কি "পাস-বাই-ভ্যালু" নয়?
ক্রিশ্চিয়ান গুটু

@ ক্রিশ্চিয়ান গুতু হ্যাঁ আপনি ঠিক বলেছেন জাভা "মান দ্বারা পাস" হ'ল "রেফারেন্স দ্বারা পাস" নয়
আরশ

রেফারেন্সটি মান হিসাবে পাস হয় !!
devv

31

আপনি যদি উপরে উল্লিখিত উইকিপিডিয়া সংজ্ঞাটি ব্যবহার করেন তবে প্রকৃতপক্ষে স্ট্রিং অপরিবর্তনীয় নয়।

স্ট্রিংয়ের রাজ্য পোস্ট নির্মাণ পরিবর্তন করে। হ্যাশকোড () পদ্ধতিটি একবার দেখুন। স্ট্রিং স্থানীয় ক্ষেত্রে হ্যাশকোড মানকে ক্যাশে করে তবে হ্যাশকোডের প্রথম কল () না হওয়া পর্যন্ত এটি গণনা করে না। হ্যাশকোডের জায়গাগুলির এই অলস মূল্যায়ন স্ট্রিংকে একটি অপরিবর্তনীয় বস্তু হিসাবে একটি আকর্ষণীয় অবস্থানে স্ট্রিং করে যার রাজ্য পরিবর্তিত হয়, তবে প্রতিবিম্বটি ব্যবহার না করে এটি পরিবর্তিত হয়েছে তা লক্ষ্য করা যায় না।

সুতরাং সম্ভবত অপরিবর্তনীয়তার সংজ্ঞাটি এমন একটি বস্তু হওয়া উচিত যা পাল্টে দেওয়া লক্ষ্য করা যায় না।

রাষ্ট্রটি তৈরি হওয়ার পরে যদি কোনও পরিবর্তনযোগ্য বস্তুর পরিবর্তিত হয় তবে কেউ এটি দেখতে পায় না (প্রতিবিম্ব ছাড়াই) বস্তুটি কি এখনও অপরিবর্তনীয়?


1
ভাল ধারণা - এমন একটি জিনিস যা পর্যবেক্ষণ করা যায় না যা পরিবর্তিত হয়েছে, পাশাপাশি এটি বাইরে থেকে পরিবর্তন করার কোনও উপায় নেই। হ্যাশকোড () এর জন্য ব্যক্তিগত ক্ষেত্রটি একটি অভ্যন্তরীণ পরিবর্তন যা বস্তুর বাহ্যিক দৃশ্যমান অবস্থার উপাদান নয়।
এমপারাজ

2
আসলে এটা করতে পরিবর্তিত হয়েছে যদি আপনি প্রতিফলন ব্যবহার পালন করা। সেডজউইকের স্ট্রিংগুলিতে আরও দেখুন যদি আপনি প্রতিবিম্বটি মঞ্জুর করেন
মিগুয়েল

24

অপরিবর্তনীয় বস্তু হ'ল এমন বস্তু যা প্রোগ্রামিয়ালি পরিবর্তন করা যায় না। তারা বিশেষত একাধিক-থ্রেডযুক্ত পরিবেশ বা অন্য পরিবেশের জন্য ভাল যেখানে একাধিক প্রক্রিয়া কোনও বস্তুর মানগুলি পরিবর্তন করতে (পরিবর্তন করতে) সক্ষম হয়।

কেবল স্পষ্ট করে বলার জন্য, স্ট্রিংবিল্ডার আসলে একটি পরিবর্তনযোগ্য অবজেক্ট, কোনও পরিবর্তনযোগ্য নয়। একটি নিয়মিত জাভা স্ট্রিং অপরিবর্তনীয় (অর্থাত একবার এটি তৈরি হয়ে গেলে আপনি অবজেক্ট পরিবর্তন না করেই অন্তর্নিহিত স্ট্রিং পরিবর্তন করতে পারবেন না)।

উদাহরণস্বরূপ, ধরা যাক যে আমার কাছে একটি রঙিন স্ট্রিং নামে একটি ক্লাস রয়েছে যার একটি স্ট্রিং মান এবং একটি স্ট্রিং রঙ রয়েছে:

public class ColoredString {

    private String color;
    private String string;

    public ColoredString(String color, String string) {
        this.color  = color;
        this.string = string;
    }

    public String getColor()  { return this.color;  }
    public String getString() { return this.string; }

    public void setColor(String newColor) {
        this.color = newColor;
    }

}

এই উদাহরণে, কলার্ডস্ট্রিংকে পরিবর্তনীয় হিসাবে বলা হয় কারণ আপনি কোনও নতুন রঙিন স্ট্রিং ক্লাস তৈরি না করেই এর অন্যতম মূল বৈশিষ্ট্য পরিবর্তন করতে (পরিবর্তন করতে পারেন)। এটির খারাপ হওয়ার কারণটি উদাহরণস্বরূপ, ধরা যাক আপনার একটি GUI অ্যাপ্লিকেশন রয়েছে যার একাধিক থ্রেড রয়েছে এবং আপনি উইন্ডোতে ডেটা প্রিন্ট করতে রঙিন স্ট্রিংস ব্যবহার করছেন। আপনার যদি রঙিন স্ট্রিংয়ের উদাহরণ থাকে যা হিসাবে তৈরি হয়েছিল

new ColoredString("Blue", "This is a blue string!");

তারপরে আপনি আশা করতে পারেন যে স্ট্রিংটি সর্বদা "নীল" হবে। অন্য কোনও থ্রেড, তবে, এই দৃষ্টান্তটির চেয়ে ভাল হয়ে উঠেছে এবং ডাকা হবে

blueString.setColor("Red");

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

জাভা.লেং.স্ট্রিং একটি অপরিবর্তনীয় বস্তু (এটি তৈরি হওয়ার পরে এটি পরিবর্তন করা যায় না ) এবং জাভা.এল.আর. স্ট্রিংবিল্ডার একটি পরিবর্তনীয় বস্তু কারণ এটি কোনও নতুন উদাহরণ তৈরি না করে পরিবর্তন করা যায় rec


আপনার ক্ষেত্রগুলি পঠনযোগ্যভাবে করা উচিত। এই মুহূর্তে আপনার ক্লাসটি কনভেনশন দ্বারা অপরিবর্তনীয়। ভবিষ্যতের বিকাশকারীদের কাছে কোনও ইঙ্গিত নেই যে স্থাবর ইচ্ছাকৃত is ক্ষেত্রগুলিকে পঠনযোগ্য করে তৈরি করা ভবিষ্যতের দেবের প্রতি আপনার উদ্দেশ্যটি স্পষ্ট করতে সহায়তা করবে
JaredPar

@ জারেডপার - আসলে, শ্রেণিটি একেবারেই স্থায়ী নয় ... কেন এটি একটি সমস্যা হতে পারে তা প্রদর্শনের জন্য এটি পরিবর্তনীয় শ্রেণীর উদাহরণ example
জেসন কোকো

1
@ জারেডপার - ওহ, এটি সম্পূর্ণ ঠিক আছে :) আমি আরও পরিষ্কার হয়ে যাবার জন্য এটি আবার লিখতে চাইছিলাম, তবে ডগলাস এরই মধ্যে ভাল লিখেছেন এবং এটি প্রিয় বলে মনে হচ্ছে, তাই আমি কেবল আমার অন্য উদাহরণ হিসাবে ছেড়ে যাব; তবে সম্পত্তিটি চূড়ান্ত করার জন্য কেউ এটি সম্পাদনা করেছিল যা আমি ভেবেছিলাম মজাদার ছিল :)
জেসন কোকো

24
  1. বড় অ্যাপ্লিকেশনগুলিতে স্ট্রিং লিটারেলের পক্ষে মেমরির বড় বিটগুলি দখল করা সাধারণ। তাই দক্ষতার মেমরির হ্যান্ডেল করতে, জেভিএম একটি এলাকা "স্ট্রিং ধ্রুবক পুকুর" নামক বরাদ্দ। ( নোট করুন যে মেমরি এমনকি একটি unreferenced স্ট্রিং একটি গৃহস্থালি [], তার দৈর্ঘ্য জন্য কোন int, এবং অন্য তার হ্যাশকোড জন্য প্রায় বহন করে। একটি সংখ্যা জন্য বিপরীতে, সর্বোচ্চ আটটি তাত্ক্ষণিক বাইট প্রয়োজন )
  2. কম্পাইলার যখন একটি স্ট্রিং আক্ষরিক জুড়ে আসে এটি পুলটি পরীক্ষা করে দেখায় যে ইতিমধ্যে কোনও অভিন্ন আক্ষরিক উপস্থিত রয়েছে কিনা to এবং যদি এটি পাওয়া যায় তবে নতুন আক্ষরিকের রেফারেন্সটি বিদ্যমান স্ট্রিংয়ের দিকে নির্দেশিত হয় এবং কোনও নতুন 'স্ট্রিং আক্ষরিক অবজেক্ট' তৈরি হয় না (বিদ্যমান স্ট্রিংটি কেবল একটি অতিরিক্ত রেফারেন্স পায়)।
  3. অতএব: স্ট্রিং মিউটেবিলিটি স্মৃতি বাঁচায় ...
  4. তবে যখন কোনও ভেরিয়েবলের মান পরিবর্তন হয়, আসলে - এটি কেবল তাদের রেফারেন্স পরিবর্তিত হয়েছে, মেমরির মান নয় (সুতরাং এটি অন্যান্য ভেরিয়েবলগুলিকে এটি উল্লেখ করবে না) নীচে দেখানো হয়েছে ....

স্ট্রিং এস 1 = "ওল্ড স্ট্রিং";

//s1 variable, refers to string in memory
        reference                 |     MEMORY       |
        variables                 |                  |

           [s1]   --------------->|   "Old String"   |

স্ট্রিং এস 2 = এস 1;

//s2 refers to same string as s1
                                  |                  |
           [s1]   --------------->|   "Old String"   |
           [s2]   ------------------------^

s1 = "নতুন স্ট্রিং";

//s1 deletes reference to old string and points to the newly created one
           [s1]   -----|--------->|   "New String"   |
                       |          |                  |
                       |~~~~~~~~~X|   "Old String"   |
           [s2]   ------------------------^

'মেমরির মূল স্ট্রিং' পরিবর্তন হয়নি, তবে রেফারেন্স ভেরিয়েবলটি পরিবর্তন করা হয়েছিল যাতে এটি নতুন স্ট্রিংকে বোঝায়। এবং যদি আমাদের এস 2 না থাকে তবে "ওল্ড স্ট্রিং" এখনও স্মৃতিতে থাকবে তবে আমরা এটি অ্যাক্সেস করতে পারব না ...


16

"অপরিবর্তনীয়" এর অর্থ আপনি মান পরিবর্তন করতে পারবেন না। যদি আপনার কাছে স্ট্রিং ক্লাসের উদাহরণ থাকে তবে যে কোনও পদ্ধতিতে আপনি কল করেন যা মানটিকে সংশোধন করে বলে মনে হচ্ছে, আসলেই অন্য একটি স্ট্রিং তৈরি করবে।

String foo = "Hello";
foo.substring(3);
<-- foo here still has the same value "Hello"

পরিবর্তনগুলি সংরক্ষণ করার জন্য আপনার এই foo = foo.sustring (3) এর মতো কিছু করা উচিত;

অপরিবর্তনীয় বনাম পরিবর্তনীয় মজার হতে পারে যখন আপনি সংগ্রহগুলি নিয়ে কাজ করেন। আপনি যদি মানচিত্রের কী হিসাবে পরিবর্তনীয় অবজেক্টটি ব্যবহার করেন এবং তারপরে মানটি পরিবর্তন করেন তবে কী হবে তা চিন্তা করুন (টিপ: সম্পর্কে চিন্তা করুন equalsএবং hashCode)।


13

java.time

এটি কিছুটা দেরিতে হতে পারে তবে একটি অপরিবর্তনীয় বস্তুটি কী তা বোঝার জন্য নতুন জাভা 8 তারিখ এবং সময় এপিআই ( জাভা.টাইম ) থেকে নিম্নলিখিত উদাহরণটি বিবেচনা করুন । আপনি সম্ভবত জানেন যে জাভা 8 থেকে সমস্ত তারিখের অবজেক্টগুলি অপরিবর্তনীয় তাই নিম্নলিখিত উদাহরণে

LocalDate date = LocalDate.of(2014, 3, 18); 
date.plusYears(2);
System.out.println(date);

আউটপুট:

2014-03-18

এটি একই বছরটিকে প্রাথমিক তারিখ হিসাবে মুদ্রণ করে কারণ plusYears(2)কোনও নতুন অবজেক্ট রিটার্ন করে তাই পুরানো তারিখটি এখনও অপরিবর্তিত কারণ এটি একটি অপরিবর্তনীয় বস্তু। একবার তৈরি হয়ে গেলে আপনি এটিকে আরও সংশোধন করতে পারবেন না এবং তারিখের চলকটি এখনও এটির দিকে নির্দেশ করে।

সুতরাং, সেই কোড উদাহরণটিকে নতুন অবজেক্টটি ক্যাপচার এবং ব্যবহার করা উচিত ইনস্ট্যান্টিয়েটেড এবং সেই কলটিতে ফিরে আসা plusYears

LocalDate date = LocalDate.of(2014, 3, 18); 
LocalDate dateAfterTwoYears = date.plusYears(2);

তারিখ.আর স্ট্রিং ()… 2014-03-18

তারিখআফটারটোউস.সট্রিং ()… 2016-03-18


8

আমি জাভা 5 স্টাডি গাইডের জন্য এসসিজেপি সান সার্টিফাইড প্রোগ্রামার থেকে ব্যাখ্যাটি সত্যিই পছন্দ করি ।

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


এটি কোনও অভিন্ন পরিবর্তনযোগ্য বস্তুর সাথে এটি করতে সক্ষম হওয়া উচিত, তবে আমি মনে করি এটির জন্য খুব বেশি রানটাইম লাগবে।
ঝ্যান লিংস

8

যে সমস্ত পদগুলি অপরিবর্তনীয় তারা তৈরি হওয়ার পরে তাদের রাষ্ট্র পরিবর্তন করতে পারে না।

আপনি যখনই পারবেন অপরিবর্তনীয় অবজেক্টগুলি ব্যবহার করার তিনটি প্রধান কারণ রয়েছে, এগুলি সবই আপনার কোডটিতে আপনি যে বাগগুলি প্রবর্তন করেছেন তা হ্রাস করতে সহায়তা করবে:

  • আপনার প্রোগ্রাম কীভাবে কাজ করে সে সম্পর্কে যুক্তিযুক্ত হওয়া অনেক সহজ যখন আপনি জানেন যে কোনও জিনিসের স্থিতি অন্য কোনও পদ্ধতি দ্বারা পরিবর্তন করা যায় না
  • অপরিবর্তনীয় বস্তুগুলি স্বয়ংক্রিয়ভাবে থ্রেড নিরাপদ (ধরে নিলে তারা নিরাপদে প্রকাশিত হয়) সুতরাং কখনই সেই হার্ড-টু-পিন-ডাউন মাল্টিথ্রেডিং বাগগুলির কারণ হতে পারে না
  • অপরিবর্তনীয় বস্তুগুলির সর্বদা একই হ্যাশ কোড থাকবে, তাই এগুলি হ্যাশম্যাপে (বা অনুরূপ) কী হিসাবে ব্যবহার করা যেতে পারে। যদি একটি হ্যাশ টেবিলের কোনও উপাদানটির হ্যাশ কোডটি পরিবর্তন করতে হয়, সারণীতে প্রবেশের ফলস্বরূপ কার্যকরভাবে হারাতে হবে, যেহেতু সারণীতে এটি সন্ধান করার চেষ্টাটি ভুল জায়গায় অনুসন্ধান করা শেষ হবে। স্ট্রিং অবজেক্টগুলি অপরিবর্তনীয় এই মূল কারণ - এগুলি প্রায়শই হ্যাশম্যাপ কী হিসাবে ব্যবহৃত হয়।

কিছু অন্যান্য অপ্টিমাইজেশন রয়েছে যা আপনি কোডে করতে সক্ষম হবেন যখন আপনি জানেন যে কোনও জিনিসের অবস্থা অপরিবর্তনীয় - উদাহরণস্বরূপ গণনা করা হ্যাশকে ক্যাশে করছে - তবে এগুলি অপটিমাইজেশন এবং অতএব আকর্ষণীয় নয়।


5

একটি অর্থ কম্পিউটারে মূল্য কীভাবে সংরক্ষণ করা হয় তার সাথে সম্পর্কিত, একটি। নেট স্ট্রিংয়ের উদাহরণস্বরূপ, এর অর্থ হ'ল মেমরির স্ট্রিংটি পরিবর্তন করা যায় না, যখন আপনি মনে করেন আপনি এটি পরিবর্তন করছেন, আপনি আসলে একটি নতুন তৈরি করছেন মেমরির স্ট্রিং এবং বিদ্যমান ভেরিয়েবলটিকে নির্দেশ করা (যা অন্য কোথাও অক্ষরের প্রকৃত সংগ্রহের কেবল পয়েন্টার) নতুন স্ট্রিংয়ের দিকে।


4
String s1="Hi";
String s2=s1;
s1="Bye";

System.out.println(s2); //Hi  (if String was mutable output would be: Bye)
System.out.println(s1); //Bye

s1="Hi": s1এটিতে "হাই" মান দিয়ে একটি অবজেক্ট তৈরি করা হয়েছিল।

s2=s1 : এস 1 অবজেক্টের s2রেফারেন্স সহ একটি অবজেক্ট তৈরি করা হয়েছে।

s1="Bye": স্ট্রিং টাইপ এবং স্ট্রিং টাইপ একটি অপরিবর্তনীয় টাইপ s1কারণ পূর্ববর্তী বস্তুর মান পরিবর্তন হয় না s1, পরিবর্তে সংকলক "বাই" মান সহ একটি নতুন স্ট্রিং অবজেক্ট তৈরি করুন এবং s1এটিতে উল্লেখ করা হয়েছে। এখানে যখন আমরা মুদ্রণ s2করব, ফলাফলটি "হাই" "বাই" নয়, কারণ s2পূর্ববর্তী s1বস্তুর সাথে "হাই" মান ছিল which


আপনি একটু ব্যাখ্যা যোগ করতে পারেন দয়া করে?
মিনিগেক

3

অপরিবর্তনীয় এর অর্থ হ'ল একবার বস্তুটি তৈরি হয়ে গেলে তার সদস্যদের মধ্যে কোনওটিই বদলে যাবে। Stringঅপরিবর্তনীয় যেহেতু আপনি এর সামগ্রী পরিবর্তন করতে পারবেন না। উদাহরণ স্বরূপ:

String s1 = "  abc  ";
String s2 = s1.trim();

উপরের কোডে, স্ট্রিং এস 1 পরিবর্তন হয়নি, অন্য একটি বস্তু ( s2) ব্যবহার করে তৈরি করা হয়েছিল s1


3

অপরিবর্তনীয় কেবল সহজ পরিবর্তন বা পরিবর্তনযোগ্য। একবার স্ট্রিং অবজেক্ট তৈরি হয়ে গেলে এর ডেটা বা রাজ্য পরিবর্তন করা যায় না

নম্র উদাহরণ বিবেচনা করুন,

class Testimmutablestring{  
  public static void main(String args[]){  
    String s="Future";  
    s.concat(" World");//concat() method appends the string at the end  
    System.out.println(s);//will print Future because strings are immutable objects  
  }  
 }  

আসুন বেলু ডায়াগ্রাম বিবেচনা করে ধারণা নেওয়া যাক,

এখানে চিত্র বর্ণনা লিখুন

এই চিত্রটিতে আপনি "ফিউচার ওয়ার্ল্ড" হিসাবে তৈরি নতুন অবজেক্ট দেখতে পাবেন। তবে "ভবিষ্যত" পরিবর্তন করবেন না। Because String is immutables, এখনও "ভবিষ্যত" দেখুন। আপনার যদি "ফিউচার ওয়ার্ল্ড" কল করতে হয়,

String s="Future";  
s=s.concat(" World");  
System.out.println(s);//print Future World

স্ট্রিং অবজেক্টস কেন জাভাতে অপরিবর্তনীয়?

কারণ জাভা স্ট্রিং আক্ষরিক ধারণাটি ব্যবহার করে। ধরুন এখানে 5 টি রেফারেন্স ভেরিয়েবল রয়েছে, সমস্তই একটি বস্তুর "ভবিষ্যত" বোঝায়। যদি একটি রেফারেন্স ভেরিয়েবলের অবজেক্টের মান পরিবর্তন হয় তবে এটি সমস্ত রেফারেন্স ভেরিয়েবলের সাথে প্রভাবিত হবে। এজন্য স্ট্রিং অবজেক্টস জাভাতে অপরিবর্তনীয়।


2

একবার তাত্ক্ষণিকভাবে পরিবর্তন করা গেলে, পরিবর্তন করা যাবে না। এমন একটি শ্রেণীর কথা বিবেচনা করুন যা উদাহরণস্বরূপ হ্যাশটেবল বা অনুরূপের কী হিসাবে ব্যবহৃত হতে পারে। জাভা সেরা অভ্যাস পরীক্ষা করে দেখুন।


0

অপরিবর্তনীয় বস্তু

কোনও বস্তু অপরিবর্তনীয় বলে বিবেচিত হয় যদি এটি তৈরির পরে তার রাজ্য পরিবর্তন করতে না পারে। অপরিবর্তনীয় বস্তুর উপর সর্বাধিক নির্ভরতা সহজ, নির্ভরযোগ্য কোড তৈরির জন্য সাউন্ড কৌশল হিসাবে ব্যাপকভাবে গৃহীত হয় accepted

অপরিবর্তনীয় বস্তুগুলি সমবর্তী অ্যাপ্লিকেশনগুলিতে বিশেষভাবে কার্যকর। যেহেতু তারা রাষ্ট্র পরিবর্তন করতে পারে না, তাই তারা থ্রেড হস্তক্ষেপ দ্বারা দূষিত হতে পারে না বা একটি বেমানান অবস্থায় লক্ষ্য করা যায়।

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

নিম্নলিখিত সাবসেকশনগুলি এমন একটি শ্রেণি নিয়েছে যার উদাহরণগুলি পরিবর্তনযোগ্য এবং এর থেকে অপরিবর্তনীয় দৃষ্টান্ত সহ একটি শ্রেণীর উদ্ভূত হয়েছে। এটি করার মাধ্যমে তারা এই ধরণের রূপান্তরকরণের জন্য সাধারণ নিয়ম দেয় এবং অপরিবর্তনীয় বস্তুর কিছু সুবিধা প্রদর্শন করে।

সূত্র


0

হিসাবে গৃহীত উত্তর সমস্ত প্রশ্নের উত্তর দেয় না। আমি 11 বছর 6 মাস পরে উত্তর দিতে বাধ্য হচ্ছি।

কেউ কি অপরিবর্তনীয় বলতে কী বোঝাতে পারে?

আশা করি আপনি স্থাবর বস্তুটি বোঝাচ্ছেন (কারণ আমরা এটি সম্পর্কে ভাবতে পারি অপরিবর্তনীয় রেফারেন্স )।

একটি বস্তু অপরিবর্তনীয় : যদি একবার তৈরি করা হয় তবে তারা সর্বদা একই মান উপস্থাপন করে (মান পরিবর্তন করে এমন কোনও পদ্ধতি নেই)।

কেন এ Stringঅপরিবর্তনীয়?

উপরের সংজ্ঞাটি সম্মান করুন যা স্টিং.জভা দেখে পরীক্ষা করা যেতে পারে উত্স কোডটি ।

অপরিবর্তনীয় বস্তুর সুবিধা / অসুবিধাগুলি কী কী? অপরিবর্তনীয় প্রকারগুলি হ'ল:

  • বাগগুলি থেকে নিরাপদ।

  • বুঝতে সহজ।

  • এবং পরিবর্তনের জন্য আরও প্রস্তুত।

স্ট্রিংবিল্ডারের মতো কোনও পরিবর্তনীয় বস্তুকে স্ট্রিং এবং ভাইস-শ্লোকের চেয়ে কেন পছন্দ করা উচিত?

প্রশ্নটি সংকুচিত করে প্রোগ্রামিংয়ে আমাদের কেন মিউটেটেবল স্ট্রিংবিল্ডারের প্রয়োজন? এর সাধারণ ব্যবহার হ'ল এক সাথে প্রচুর পরিমাণে স্ট্রিং একসাথে করা, এরকম:

String s = "";
for (int i = 0; i < n; ++i) {
    s = s + n;
}

অপরিবর্তনীয় স্ট্রিং ব্যবহার করে এটি প্রচুর অস্থায়ী অনুলিপি তৈরি করে - স্ট্রিংয়ের প্রথম সংখ্যাটি ("0") আসলে চূড়ান্ত স্ট্রিংটি তৈরির সময় এন বার অনুলিপি করা হয়, দ্বিতীয় সংখ্যাটি এন -1 বার অনুলিপি করা হয়, এবং তাই চালু. এটি অনুলিপি করার জন্য আসলে ও (এন 2) সময় ব্যয় হয়, যদিও আমরা কেবল এন উপাদানগুলিকে সম্মতি জানাই।

স্ট্রিংবিল্ডার এই অনুলিপিটি হ্রাস করার জন্য ডিজাইন করা হয়েছে। আপনি কোনও স্ট্রিং () কল দিয়ে চূড়ান্ত স্ট্রিংয়ের জন্য জিজ্ঞাসা করার সময় একেবারে শেষ অবধি কোনও অনুলিপি করা এড়াতে এটি একটি সহজ তবে চতুর অভ্যন্তরীণ ডেটা কাঠামো ব্যবহার করে:

StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; ++i) {
  sb.append(String.valueOf(n));
}
String s = sb.toString();

ভাল পারফরম্যান্স পাওয়া আমাদের পারস্পরিক পরিবর্তনযোগ্য জিনিসগুলি কেন ব্যবহার করার একটি কারণ। অন্যটি সুবিধাজনক ভাগ করে নেওয়া: আপনার প্রোগ্রামের দুটি অংশ একটি সাধারণ পরিবর্তনীয় ডেটা কাঠামো ভাগ করে আরও সহজেই যোগাযোগ করতে পারে।

আরও এখানে পাওয়া যাবে: https://web.mit.edu/6.005/www/fa15/classes/09- অনিবার্যতা /# ব্যবহার্য_আম্মে পরিবর্তনযোগ্য_প্রকার


-1

অপরিবর্তনীয় বস্তু হ'ল এটি তৈরির পরে আপনি যা পরিবর্তন করতে পারবেন না। একটি আদর্শ উদাহরণ স্ট্রিং আক্ষরিক হয়।

এডি প্রোগ্রামিং ল্যাঙ্গুয়েজ, যা ক্রমবর্ধমান জনপ্রিয় হয়ে উঠেছে, "আক্রমণকারী" কীওয়ার্ডের মাধ্যমে "অপরিবর্তনীয়তা" ধারণা রয়েছে। এটি সম্পর্কে এই ডাঃডব এর নিবন্ধটি দেখুন - http://dobbscodetalk.com/index.php?option=com_myblog&show=Ivvariant-Strings.html&Itid=29 । এটি সমস্যার পুরোপুরি ব্যাখ্যা করে।


আমি বিশ্বাস করি যে ডি 2.020 এর হিসাবে কীওয়ার্ডটি আক্রমণকারী থেকে অচল হয়ে যায়। আমি একটি বিন্দু দেখতে পাচ্ছি না, তবে এটি বলে, "অপরিবর্তনীয় এখন বাস্তবায়ন করা হয়েছে।" digitalmars.com/d/2.0/changelog.html#new2_020
he_the_great
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.