আপনি কখন জাভাতে ভারারা ব্যবহার করবেন?


192

আমি ভ্যারাগস থেকে ভয় পাই। আমি জানি না এগুলির জন্য কী ব্যবহার করতে হবে।

এছাড়াও, লোকেরা যত খুশি তত যুক্তি পাস করতে দেওয়া বিপজ্জনক বোধ করে।

এমন একটি প্রসঙ্গের উদাহরণ কী যা সেগুলি ব্যবহারের জন্য ভাল জায়গা হবে?


3
কেন এটি "বিপজ্জনক" হবে তা আমি দেখছি না। বিভিন্ন আর্গুমেন্ট সহ একটি বড় সংখ্যক বার বলা পদ্ধতি থাকা ছাড়া এটি বিপজ্জনক নয়। স্ট্যাক নিয়ে আপনার কি উদ্বেগ আছে? তারপরে আপনার উচিত হবে না, কারণ ভ্যারেজগুলি অ্যারেতে ম্যাপ করা হয় যা রেফারেন্স দ্বারা পাস করা হয়।
jfpoil ব্যাখ্যা 4

66
কেবল চিম ইন করতে চেয়েছিলেন: আপনি যে ভাষা বৈশিষ্ট্যগুলি (এখনও) পুরোপুরি স্বাচ্ছন্দ্যবোধ করেন না সেগুলি এড়িয়ে চলা কোনও ভুল নেই। আপনি যে বৈশিষ্ট্যগুলি বুঝতে পারছেন না তার চেয়ে আরও ভাল! ;)
স্টিভেন

2
অজানা আশঙ্কা করা স্বাভাবিক। ভারার্গস সম্পর্কে আরও পড়তে এখানে ডকস.ওরকল / জ্যাভেস / টিউটোরিয়াল / জাভা / জাভা ওআরগামেন্টস html । আপনি দেখতে পাবেন, যে ভারারাগুলি ভয় পাওয়ার মতো কিছুই নয়। Varargs দরকারী। ভারারাগস কীভাবে ব্যবহার করতে হয় তা জানার ফলে আপনি [মুদ্রণপ্রবাহ.ফর্ম্যাট] (" ডকস.ওরকল / জাভাসে / / / ডকস / এপি / জাভা / আইও , জাভা.ল্যাং.অবজেক্ট ...) এর মতো পদ্ধতিগুলি লেখার ক্ষমতা পান " ) :)।
বিকাশকারী মারিয়াস Žilėnas

1
এটি ভারার্গসের সমালোচনা নয়, তবে "ভয় পাওয়ার" কারণ রয়েছে (যতক্ষণ না আপনি ভাল্যারাগসের সীমাবদ্ধতা অবিকল বুঝতে না পারছেন); এই কারণেই @ সেফভারার্স টিকা আছে exists stackoverflow.com/a/14252221/1593924
জন Coombs

উত্তর:


150

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

String.format("This is an integer: %d", myInt);
String.format("This is an integer: %d and a string: %s", myInt, myString);

5
একটি অ্যারে প্যারামিটারও অনির্দিষ্ট সংখ্যক অবজেক্টগুলি পেতে পারে তবে একটি ভার্সেস প্যারামিটার অনুরোধের সময় আরও নমনীয়তা এবং সুবিধার্থে অনুমতি দেয়। আপনি একটি অ্যারে তৈরি করতে এবং এটি পাস করার জন্য কোড লিখতে পারেন বা যখন আপনি ভারার্গ্স প্যারামিটারে এটি গ্রহণ করতে চান তখন জাভা আপনার জন্য এটি করতে দিতে পারেন।
H2ONaCl

79

থাম্ব একটি ভাল নিয়ম হবে:

"ইনপুট হিসাবে যে কোনও পদ্ধতির (বা নির্মাণকারী) এর জন্য টি এর অ্যারের প্রয়োজন (যে কোনও ধরণের টি হতে পারে) এর জন্য ভারারাগগুলি ব্যবহার করুন"।

এটি এই পদ্ধতিগুলিতে কলগুলি আরও সহজ করে দেবে (করার দরকার নেই) new T[]{...} )।

একটি সহ পদ্ধতিগুলি অন্তর্ভুক্ত করতে আপনি এই নিয়মটি বাড়িয়ে দিতে পারেন List<T> আর্গুমেন্ট , তবে এই শর্তটি কেবল ইনপুট (যেমন, তালিকাটি পদ্ধতি দ্বারা সংশোধিত হয় না) provided

অতিরিক্তভাবে, আমি ব্যবহার থেকে বিরত থাকব f(Object... args) কারণ এটি অস্পষ্ট APIs সহ একটি প্রোগ্রামিংয়ের দিকে পিছলে যায়।

উদাহরণস্বরূপ, আমি এটি ডিজাইনগ্রিডলাআউটে ব্যবহার করেছি , যেখানে আমি JComponentএকটি কলে বেশ কয়েকটি গুলি যুক্ত করতে পারি :

layout.row().grid(new JLabel("Label")).add(field1, field2, field3);

উপরের কোডে অ্যাড () পদ্ধতিটি হিসাবে সংজ্ঞায়িত করা হয়েছে add(JComponent... components)

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

void f(T arg1, T... args) {...}

আমি এই কৌশলটিকে কুরুচিপূর্ণ বলে বিবেচনা করি কারণ পদ্ধতির প্রয়োগটি ন্যায়বিচারের চেয়ে কম সহজ হবে T... args তার যুক্তি তালিকায় ।

আশা করে এটি ভারার্গস সম্পর্কে পয়েন্টটি পরিষ্কার করতে সহায়তা করে।


1
আপনি কি if (args.length == 0) throw new RuntimeException("foo");পরিবর্তে পূর্ব শর্ত পরীক্ষা করে বিবেচনা করেছেন ? (যেহেতু কলার চুক্তি লঙ্ঘন করছে)
মিখা উইডেনম্যান

24
ভাল, একটি ভাল এপিআই এর উদ্দেশ্য হ'ল যত তাড়াতাড়ি সম্ভব অপব্যবহার রোধ করা, সুতরাং এটি সম্ভব হওয়ার সময় সংকলন করার জন্য, সুতরাং এর পরামর্শটি void f(T arg1, T... args)সর্বদা এটি নিশ্চিত করে যে এটি রান আউট অবধি অপেক্ষা করার প্রয়োজন ছাড়াই কোনও যুক্তি ছাড়াই ডাকা হবে না।
jfpoil ব্যাখ্যা

আমি মনে করি বেশিরভাগ সময় কোনও বিতর্ক ছাড়াই কোনও ভারার্গস-ফাংশনটিতে কল করা মোটেও কিছু না করার পরিমাণ। পয়েন্টটি হ'ল কোনও ভারার্গস ফাংশনে কোনও যুক্তি সরবরাহ করা সম্ভবত যথেষ্ট ক্ষতি করতে যাচ্ছে না।
ওয়ার্ল্ডসেন্ডার

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

34

আমি ডিবাগিংয়ের উদ্দেশ্যে লগগুলিতে আউটপুট দেওয়ার জন্য ঘন ঘন ভ্যারাগ ব্যবহার করি।

আমার অ্যাপ্লিকেশনের প্রতিটি ক্লাসে একটি পদ্ধতি ডিবাগপ্রিন্ট রয়েছে ():

private void debugPrint(Object... msg) {
    for (Object item : msg) System.out.print(item);
    System.out.println();
}

তারপরে, ক্লাসের পদ্ধতিগুলির মধ্যে আমার কাছে নিম্নলিখিতগুলির মতো কল রয়েছে:

debugPrint("for assignment ", hwId, ", student ", studentId, ", question ",
    serialNo, ", the grade is ", grade);

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

অবশ্যই আমি খুব সহজেই ভারার্গগুলি রোধ করতে এবং এর পরিবর্তে নিম্নলিখিতগুলি করতে পারি:

private void debugPrint(String msg) {
    System.out.println(msg);
}

debugPrint("for assignment " + hwId + ", student " + studentId + ", question "
    + serialNo + ", the grade is " + grade);

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


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

12

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

আমাদের যদি এমন একটি পদ্ধতি থাকে যা বিভিন্ন সংখ্যক পরামিতি গ্রহণ করার জন্য ওভারলোড হয়, তবে পদ্ধতিটি বিভিন্ন সময় ওভারলোডের পরিবর্তে আমরা কেবল ভারার্গ্স ধারণাটি ব্যবহার করতে পারি।

এছাড়াও যখন পরামিতিগুলির ধরণ পরিবর্তিত হয় তখন "অবজেক্ট ... পরীক্ষা" ব্যবহার করে কোডটি অনেক সহজ করা যায়।

উদাহরণ স্বরূপ:

public int calculate(int...list) {
    int sum = 0;
    for (int item : list) {
        sum += item;
    }
    return sum;
}

এখানে পরোক্ষভাবে int টাইপ (তালিকা) এর একটি অ্যারে প্যারামিটার হিসাবে পাস হয় এবং কোডটিতে অ্যারে হিসাবে বিবেচিত হয়।

আরও ভাল বোঝার জন্য এই লিঙ্কটি অনুসরণ করুন (এটি এই ধারণাটি পরিষ্কারভাবে বুঝতে আমার অনেক সহায়তা করেছে): http://www.javadb.com/ using-varargs-in- java

পিএস: এমনকি আমি ভারাক্রজগুলি ব্যবহার করতে ভয় পেয়েছিলাম যখন আমি এটিটি বন্ধ করি নি afraid তবে এখন আমি অভ্যস্ত। যেমনটি বলা হয়: "আমরা পরিচিতদের সাথে পরিচিত, অজানা থেকে ভয় পেয়েছি", তাই এটি যতটা সম্ভব ব্যবহার করুন এবং আপনিও এটি পছন্দ করতে শুরু করবেন :)


4
সি # ভারারাগের সমতুল্য হ'ল "প্যারাম"। এটি একই জিনিসটি করে এবং পরিবর্তনশীল সংখ্যক পরামিতি গ্রহণ করে। আরও বোঝার জন্য এটি দেখুন: dotnetperls.com/params
সারভান

11

ভার্জগুলি জাভা সংস্করণ 1.5 তে যুক্ত করা বৈশিষ্ট্য।

কেন এটি ব্যবহার করবেন?

  1. কী হবে যদি আপনি কোনও পদ্ধতির জন্য পাস করার জন্য আর্গুমেন্টের সংখ্যা জানেন না?
  2. আপনি যদি কোনও পদ্ধতিতে সীমাহীন সংখ্যক যুক্তি পাস করতে চান?

এটি কিভাবে কাজ করে?

এটি প্রদত্ত যুক্তিগুলির সাহায্যে একটি অ্যারে তৈরি করে এবং অ্যারেটিকে পদ্ধতিতে পাস করে।

উদাহরণ:

public class Solution {



    public static void main(String[] args) {
        add(5,7);
        add(5,7,9);
    }

    public static void add(int... s){
        System.out.println(s.length);
        int sum=0;
        for(int num:s)
            sum=sum+num;
        System.out.println("sum is "+sum );
    }

}

আউটপুট:

2

যোগফল 12

3

যোগফল 21


6

আমারও ভ্যারাগস-সম্পর্কিত ভয় রয়েছে:

যদি কলার পদ্ধতিটিতে সুস্পষ্ট অ্যারে পাস করে (একাধিক পরামিতিগুলির বিপরীতে), আপনি সেই অ্যারেটির একটি ভাগ করে নেওয়া রেফারেন্স পাবেন।

আপনার যদি এই অ্যারেটি অভ্যন্তরীণভাবে সঞ্চয় করতে হয় তবে আপনি কলার পরে এটি পরিবর্তন করতে সক্ষম না হওয়ার জন্য প্রথমে এটি ক্লোন করতে চাইতে পারেন।

 Object[] args = new Object[] { 1, 2, 3} ;

 varArgMethod(args);  // not varArgMethod(1,2,3);

 args[2] = "something else";  // this could have unexpected side-effects

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


1
সঠিক, তবে এই উদাহরণটি খানিকটা দূরের বলে মনে হচ্ছে। লোকেরা কি সম্ভবত আপনার এপিআই ব্যবহার করবে?
jfpoil ব্যাখ্যা 1

2
আপনি কখনই জানেন না ... এবং বিশেষত যখন আর্গুমেন্টগুলির সংখ্যা কলিং সাইডে কঠোর কোডড হয় না, তবে একটি লুপের মধ্যে একটি তালিকাতে সংগ্রহ করা সংগ্রহ করা হয়, অ্যারেতে পাস করা সমস্ত অস্বাভাবিক নয়।
থিলো

5
আমি মনে করি আপনার ব্যবহারের ক্ষেত্রে উদাহরণটি সাধারণত বলার অপেক্ষা রাখে না। কেউ তর্ক করতে পারে যে আপনার API এর ইনপুট অ্যারে এইভাবে ব্যবহার করা উচিত নয়, এবং যদি এটি হয় তবে এটি অবশ্যই এটি নথী করে।
লরেন্স ডল

উভয় সমর্থন করার জন্য পদ্ধতি ওভারলোড; #Method (অবজেক্ট .. আপত্তি তালিকা) argMethod (অবজেক্ট [] আপত্তি তালিকা)
thetoolman

2
@ থিয়েলম্যান: আমি মনে করি না এটি সম্ভব। এটি একটি সদৃশ পদ্ধতি হিসাবে বিবেচিত হবে।
থিলো

1

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


1

ভার-আরগ্সের জাভা নথিতে এটি ভার আর্গগুলির ব্যবহারটি পরিষ্কারভাবে স্পষ্ট করেছে:

http://docs.oracle.com/javase/1.5.0/docs/guide/language/varargs.html

ব্যবহার সম্পর্কে এটি বলে:

"সুতরাং যখন আপনাকে ভারারাগস ব্যবহার করা উচিত? ক্লায়েন্ট হিসাবে, যখনই এপিআই তাদের প্রস্তাব দেয় তখন আপনাকে সেগুলি গ্রহণ করা উচিত core অল্প কথায়, কেবল তখনই যখন সুবিধাটি সত্যই জোরালো।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.