আমি জাভাতে পরিবর্তনশীল আর্গুমেন্ট সহ কোনও পদ্ধতিতে আর্গুমেন্ট হিসাবে একটি অ্যারে পাস করতে পারি?


275

আমি একটি ফাংশন তৈরি করতে সক্ষম হতে চাই:

class A {
  private String extraVar;
  public String myFormat(String format, Object ... args){
    return String.format(format, extraVar, args);
  }
}

এখানে সমস্যা হল argsহিসাবে গণ্য হবে Object[]পদ্ধতিতে myFormat, এবং এইভাবে একটি একক যুক্তি String.formatযখন আমি চাই প্রতিটি, Objectমধ্যে argsএকটি নতুন আর্গুমেন্ট হিসাবে পাস করা হবে। যেহেতু String.formatপরিবর্তনশীল আর্গুমেন্ট সহ একটি পদ্ধতিও এটি সম্ভব হওয়া উচিত।

যদি এটি সম্ভব না হয় তবে এর মতো কোনও পদ্ধতি আছে String.format(String format, Object[] args)কি? সেক্ষেত্রে আমি একটি নতুন অ্যারে ব্যবহার extraVarকরার জন্য প্রিপেন্ড করতে পারি argsএবং এটি সেই পদ্ধতিতে পাস করতে পারি।


8
আমি সাহায্য করতে পারছি না তবে ভাবছি কেন এই প্রশ্নটি "এই বৈধ" ধরণের প্রশ্ন। আপনি কি শুধু চেষ্টা করে দেখতে পারছেন না? অতিরিক্ত জিজ্ঞাসা করবেন না, আপনি নিজের চেয়ে ভাল ক্ষতি করবেন।
কামশেটো

21
যথেষ্ট সত্য, এটি সহজে পরীক্ষা করা যেতে পারে। যাইহোক, এই জাতীয় একটি প্রশ্ন সম্পর্কে দুর্দান্ত জিনিস এটি বিষয় প্রকাশ করে এবং আকর্ষণীয় উত্তর চেয়ে।
akf

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

উত্তর:


180

একটি variadic পদ্ধতির অন্তর্নিহিত টাইপ function(Object... args) হয় function(Object[] args) । পিছনে সামঞ্জস্যতা রক্ষার জন্য সূর্য এই পদ্ধতিতে ভারারা যুক্ত করেছে।

সুতরাং আপনি কেবল প্রিপেন্ড extraVarকরতে argsএবং কল করতে সক্ষম হবেন String.format(format, args)


X[]কোনও পদ্ধতিতে প্রকারের আর্গুমেন্টটি পাঠানো গ্রহণায় x(X... xs)নিম্নলিখিত সতর্কতা দেয়:Type X[] of the last argument to method x(X...) doesn't exactly match the vararg parameter type. Cast to X[] to confirm the non-varargs invocation, or pass individual arguments of type X for a varargs invocation.
লুক হাচিসন

318

হ্যাঁ, একটি T...এটির জন্য কেবল একটি সিনট্যাকটিক চিনিT[]

জেএলএস 8.4.1 ফর্ম্যাট পরামিতি

একটি তালিকার সর্বশেষ আনুষ্ঠানিক পরামিতি বিশেষ; এটি একটি পরিবর্তনশীল আরটি হতে পারে পরামিতি , ধরণের অনুসরণ করে একটি এলিপসিস দ্বারা নির্দেশিত।

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

উদাহরণস্বরূপ এখানে উদাহরণ দেওয়া হল:

public static String ezFormat(Object... args) {
    String format = new String(new char[args.length])
        .replace("\0", "[ %s ]");
    return String.format(format, args);
}
public static void main(String... args) {
    System.out.println(ezFormat("A", "B", "C"));
    // prints "[ A ][ B ][ C ]"
}

এবং হ্যাঁ, উপরের mainপদ্ধতিটি বৈধ, কারণ আবারও String...ন্যায়সঙ্গত String[]। এছাড়াও, অ্যারেগুলি সমবায় যেহেতু, এটি String[]হ'ল Object[]তাই আপনি কল করতেও পারেনezFormat(args) কোনও উপায়ে ।

আরো দেখুন


ভারার্গস গেটছস # 1: পাস করছে null

ভারার্গগুলি কীভাবে সমাধান করা হয় তা বেশ জটিল এবং কখনও কখনও এটি এমন কিছু করে যা আপনাকে অবাক করে।

এই উদাহরণ বিবেচনা করুন:

static void count(Object... objs) {
    System.out.println(objs.length);
}

count(null, null, null); // prints "3"
count(null, null); // prints "2"
count(null); // throws java.lang.NullPointerException!!!

কিভাবে ভারার্গস মীমাংসা করা হয় কারণে গত বিবৃতি পূজা objs = null, অবশ্যই যা কারণ হবে NullPointerExceptionসঙ্গে objs.length। আপনি যদি nullভারার্গ্স প্যারামিটারে একটি যুক্তি দিতে চান তবে আপনি নিম্নলিখিতগুলির মধ্যে দুটি করতে পারেন:

count(new Object[] { null }); // prints "1"
count((Object) null); // prints "1"

সম্পর্কিত প্রশ্নগুলি

নীচে ভারারাগুলি নিয়ে কাজ করার সময় লোকেরা জিজ্ঞাসা করা কয়েকটি প্রশ্নের একটি নমুনা:


ভারারগ গেটচেস # 2: অতিরিক্ত যুক্তি যুক্ত করা

যেমনটি আপনি খুঁজে পেয়েছেন, নিম্নলিখিতগুলি "কাজ করে না":

    String[] myArgs = { "A", "B", "C" };
    System.out.println(ezFormat(myArgs, "Z"));
    // prints "[ [Ljava.lang.String;@13c5982 ][ Z ]"

ভারার্গস যেভাবে কাজ করে তার কারণে ezFormatআসলে 2 টি আর্গুমেন্ট পাওয়া যায়, প্রথমটি হ'ল একটি String[], দ্বিতীয়টি একটি String। আপনি যদি ভারেগগুলিতে একটি অ্যারে পাস করে চলেছেন এবং এর উপাদানগুলি পৃথক যুক্তি হিসাবে স্বীকৃতি পেতে চান এবং আপনাকে অতিরিক্ত যুক্তি যুক্ত করতে হবে তবে অতিরিক্ত উপাদান যুক্ত করে এমন একটি অ্যারে তৈরি করা ছাড়া আপনার আর কোনও উপায় নেই ।

এখানে কিছু সহায়ক সহায়ক পদ্ধতি রয়েছে:

static <T> T[] append(T[] arr, T lastElement) {
    final int N = arr.length;
    arr = java.util.Arrays.copyOf(arr, N+1);
    arr[N] = lastElement;
    return arr;
}
static <T> T[] prepend(T[] arr, T firstElement) {
    final int N = arr.length;
    arr = java.util.Arrays.copyOf(arr, N+1);
    System.arraycopy(arr, 0, arr, 1, N);
    arr[0] = firstElement;
    return arr;
}

এখন আপনি নিম্নলিখিতটি করতে পারেন:

    String[] myArgs = { "A", "B", "C" };
    System.out.println(ezFormat(append(myArgs, "Z")));
    // prints "[ A ][ B ][ C ][ Z ]"

    System.out.println(ezFormat(prepend(myArgs, "Z")));
    // prints "[ Z ][ A ][ B ][ C ]"

ভারার্গস গেটচস # 3: আদিম একটি অ্যারে পেরিয়ে যাচ্ছে

এটি "কাজ" করে না:

    int[] myNumbers = { 1, 2, 3 };
    System.out.println(ezFormat(myNumbers));
    // prints "[ [I@13c5982 ]"

Varargs কেবল রেফারেন্স ধরণের সাথে কাজ করে। আদিবক্সিং আদিমগুলির অ্যারেতে প্রযোজ্য না। নিম্নলিখিত কাজগুলি:

    Integer[] myNumbers = { 1, 2, 3 };
    System.out.println(ezFormat(myNumbers));
    // prints "[ 1 ][ 2 ][ 3 ]"

2
অবজেক্ট ব্যবহার করে ... বৈকল্পিক প্যারামিটারগুলি অতিরিক্ত স্বাক্ষরগুলি ব্যবহার করা কঠিন করে তোলে কারণ সংকলক যেখানে স্বাক্ষর করতে পারে এমনকি কোনও প্রাথমিক আর্গুমেন্ট অবজেক্টে স্বতঃবক্স করা যেতে পারে তাই সংকলক স্বাক্ষরগুলির মধ্যে অস্পষ্টতা চিহ্নিত করে।
ইয়েল ghEEz

7
একটি অনুপস্থিত গোচাচা রয়েছে: যদি আপনার পদ্ধতিতে অবজেক্ট টাইপ করার শেষ প্যারাম থাকে ... এবং আপনি এটিকে একটি স্ট্রিং পাস করার আহ্বান জানিয়েছেন [] উদাহরণস্বরূপ। সংকলকটি জানে না যে আপনার অ্যারেটি ভারাজগুলির প্রথম আইটেম কিনা বা সমস্ত ভারারসের সমতুল্য। এটি আপনাকে সতর্ক করবে।
Snicolas

X[]কোনও পদ্ধতিতে প্রকারের আর্গুমেন্টটি পাঠানো গ্রহণায় x(X... xs)নিম্নলিখিত সতর্কতা দেয়:Type X[] of the last argument to method x(X...) doesn't exactly match the vararg parameter type. Cast to X[] to confirm the non-varargs invocation, or pass individual arguments of type X for a varargs invocation.
লুক হাচিসন

23

অ্যারে পাস করা ঠিক আছে - বাস্তবে এটি একই জিনিসটির সমান

String.format("%s %s", "hello", "world!");

হিসাবে একই

String.format("%s %s", new Object[] { "hello", "world!"});

এটি কেবল সিনট্যাকটিক চিনি - সংকলকটি প্রথমটিকে দ্বিতীয়কে রূপান্তর করে, যেহেতু অন্তর্নিহিত পদ্ধতিটি ভারাক প্যারামিটারের জন্য অ্যারের আশা করে ।

দেখা


4

jasonmp85 ঠিক আলাদা আলাদা অ্যারে পাস করার বিষয়ে String.format। একবারে অ্যারের আকার পরিবর্তন করা যায় না, সুতরাং আপনাকে বিদ্যমানটি সংশোধন না করে নতুন অ্যারে পাস করতে হবে।

Object newArgs = new Object[args.length+1];
System.arraycopy(args, 0, newArgs, 1, args.length);
newArgs[0] = extraVar; 
String.format(format, extraVar, args);

1

আমি একই সমস্যা ছিল।

String[] arr= new String[] { "A", "B", "C" };
Object obj = arr;

এবং তারপরে আপত্তিটি varargs আর্গুমেন্ট হিসাবে পাস করেছে। এটা কাজ করেছে.


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