জাভা 14 রেকর্ড এবং অ্যারে


11

নিম্নলিখিত কোড দেওয়া:

public static void main(String[] args) {
    record Foo(int[] ints){}

    var ints = new int[]{1, 2};
    var foo = new Foo(ints);
    System.out.println(foo); // Foo[ints=[I@6433a2]
    System.out.println(new Foo(new int[]{1,2}).equals(new Foo(new int[]{1,2}))); // false
    System.out.println(new Foo(ints).equals(new Foo(ints))); //true
    System.out.println(foo.equals(foo)); // true
}

মনে হয়, স্পষ্টতই, অ্যারেরগুলির toString, equalsপদ্ধতিগুলি ব্যবহার করা হয় (স্থির পদ্ধতিগুলির পরিবর্তে Arrays::equals, Arrays::deepEquals বা Array::toString)।

সুতরাং আমি অনুমান করি জাভা 14 রেকর্ডস ( জেপি 359 ) অ্যারেগুলির সাথে খুব ভাল কাজ করে না, সম্পর্কিত পদ্ধতিগুলি একটি আইডিই দিয়ে তৈরি করতে হবে (যা অন্তত IntelliJ এ, ডিফল্টরূপে "দরকারী" পদ্ধতি উত্পন্ন করে, যেমন তারা স্থির পদ্ধতিগুলি ব্যবহার করে) in Arrays)।

নাকি অন্য কোন সমাধান আছে?


3
Listঅ্যারের পরিবর্তে ব্যবহার সম্পর্কে কীভাবে ?
ওলেগ

আমি বুঝতে পারি না কেন এই জাতীয় পদ্ধতিগুলি আইডিই দিয়ে তৈরি করতে হবে? সমস্ত পদ্ধতি হাতে হাতে উত্পন্ন করতে সক্ষম হওয়া উচিত।
NomadMaker

1
toString(), equals()এবং hashCode()রেকর্ড পদ্ধতি প্রয়োগ করা হয় একটি invokedynamic রেফারেন্স ব্যবহার করে। । যদি কেবল সংকলিত শ্রেণীর সমতুল্য Arrays.deepToStringপদ্ধতিটি আজ তার ব্যক্তিগত ওভারলোডেড পদ্ধতিতে কী করে তার কাছাকাছি থাকতে পারত , তবে সম্ভবত এটি আদিমতার ক্ষেত্রে সমাধান করতে পারত।
নমন

1
বাস্তবায়নের জন্য নকশার পছন্দটিকে দ্বিতীয় স্থানে রাখার জন্য, এই পদ্ধতির কোনও ওভাররাইড বাস্তবায়ন সরবরাহ না করার জন্য, এটির পিছনে পড়া খারাপ ধারণা নয় Object, যেহেতু এটি ব্যবহারকারী-সংজ্ঞায়িত শ্রেণীর ক্ষেত্রেও ঘটতে পারে। উদাহরণস্বরূপ ভুল সমান
নমন

1
@ নমান ব্যবহারের পছন্দটির invokedynamicশব্দার্থবিজ্ঞানের বাছাইয়ের সাথে একেবারেই কিছু করার নেই; indy এখানে একটি বিশুদ্ধ বাস্তবায়ন বিশদ। সংকলক একই কাজ করতে বাইটোকড নির্গমন করতে পারে; এটি সেখানে পৌঁছানোর আরও কার্যকর এবং নমনীয় উপায় ছিল। রেকর্ডগুলির ডিজাইনের সময় এটি আরও সংখ্যক সামঞ্জস্যপূর্ণ সাম্যবাদী শব্দ ব্যবহার করতে হবে (যেমন অ্যারেগুলির জন্য গভীর সমতা) ব্যবহার করার বিষয়ে ব্যাপক আলোচনা করা হয়েছিল, তবে এটি সম্ভবত এটির সমাধানের চেয়ে আরও বেশি সমস্যার কারণ হতে পারে।
ব্রায়ান গয়েটজ

উত্তর:


18

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

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

এটি বলেছিল, আপনি যে শব্দার্থকতা চান তা দিয়ে একটি রেকর্ড ঘোষণা করতে পারেন, এটি আরও বেশি কাজ নেয় এবং আপনার মনে হতে পারে যে এটি খুব বেশি কাজ। এখানে একটি রেকর্ড রয়েছে যা আপনি যা চান তা করে:

record Foo(String[] ss) {
    Foo { ss = ss.clone(); }
    String[] ss() { return ss.clone(); }
    boolean equals(Object o) { 
        return o instanceof Foo 
            && Arrays.equals(((Foo) o).ss, ss);
    }
    int hashCode() { return Objects.hash(Arrays.hashCode(ss)); }
}

এটি যা করে তা (কনস্ট্রাক্টারে) এবং বেরোনোর ​​পথে (অ্যাক্সেসরে থাকা) প্রতিরোধমূলক অনুলিপি, পাশাপাশি অ্যারের সামগ্রীগুলি ব্যবহার করার জন্য সাম্য শব্দার্থকে সামঞ্জস্য করা। এটি সুপারক্লাসে প্রয়োজনীয় আক্রমণকারীকে সমর্থন করে java.lang.Recordযে "তার উপাদানগুলির মধ্যে একটি রেকর্ড আলাদা করে নিয়ে এবং উপাদানগুলিকে নতুন রেকর্ডে পুনর্গঠন করলে সমান রেকর্ড আসে yield"

আপনি ভাল বলতে পারেন "তবে এটি খুব বেশি কাজ, আমি রেকর্ডগুলি ব্যবহার করতে চেয়েছিলাম যাতে আমাকে সমস্ত জিনিস টাইপ করতে হবে না।" তবে, রেকর্ডগুলি মূলত একটি সিনট্যাকটিক সরঞ্জাম নয় (যদিও তারা সিনট্যাক্টিকালি আরও সুখকর) তবে সেগুলি একটি সিনমেটিক সরঞ্জাম: রেকর্ডগুলি নামমাত্র টিউপস । বেশিরভাগ সময়, কমপ্যাক্ট সিনট্যাক্স থেকেও কাঙ্ক্ষিত শব্দার্থ আবিষ্কার হয়, তবে আপনি যদি বিভিন্ন শব্দার্থবিজ্ঞান চান তবে আপনাকে কিছু অতিরিক্ত কাজ করতে হবে।


6
এছাড়াও, এটি লোকেদের দ্বারা করা সাধারণ ভুল যারা আকাঙ্ক্ষিতভাবে অ্যারে সমতা ছিল তা অনুমান করার জন্য যে কেউ কখনও রেফারেন্সের মাধ্যমে অ্যারে সমতা চায় না। তবে এটি কেবল সত্য নয়; এটি কেবলমাত্র এমন কোনও উত্তর নেই যা সমস্ত ক্ষেত্রে কাজ করে। কখনও কখনও রেফারেন্সের সাম্যতা হ'ল যা আপনি চান।
ব্রায়ান গয়েটজ

9

List< Integer > কার্যসংক্রান্ত

কার্যসংক্রান্ত: ব্যবহার একটি Listএর Integerবস্তু ( List< Integer >প্রিমিটিভের এর অ্যারে) বদলে ( int[])।

এই উদাহরণে, আমি জাভা 9-তে যুক্ত হওয়া বৈশিষ্ট্যটি ব্যবহার করে অনির্ধারিত শ্রেণীর একটি অযৌক্তিকর তালিকাটি ইনস্ট্যান্ট করি List.ofYou আপনি ArrayListঅ্যারে দ্বারা সমর্থিত একটি সংশোধনযোগ্য তালিকার জন্য ঠিক তেমন ব্যবহার করতে পারেন ।

package work.basil.example;

import java.util.List;

public class RecordsDemo
{
    public static void main ( String[] args )
    {
        RecordsDemo app = new RecordsDemo();
        app.doIt();
    }

    private void doIt ( )
    {

        record Foo(List < Integer >integers)
        {
        }

        List< Integer > integers = List.of( 1 , 2 );
        var foo = new Foo( integers );

        System.out.println( foo ); // Foo[integers=[1, 2]]
        System.out.println( new Foo( List.of( 1 , 2 ) ).equals( new Foo( List.of( 1 , 2 ) ) ) ); // true
        System.out.println( new Foo( integers ).equals( new Foo( integers ) ) ); // true
        System.out.println( foo.equals( foo ) ); // true
    }
}

অ্যারের উপরে তালিকাটি বেছে নেওয়া যদিও এটি সর্বদা ভাল ধারণা নয় এবং আমরা যাইহোক
নামান

@ নমান আমি কখনই "ভাল ধারণা" হওয়ার বিষয়ে দাবি করি নি। আক্ষরিকভাবে প্রশ্নটি অন্যান্য সমাধানগুলির জন্য জিজ্ঞাসা করেছিল। আমি একটি সরবরাহ। এবং আপনি যে মন্তব্যগুলি লিঙ্ক করেছেন তার এক ঘন্টা আগে আমি তা করেছি।
তুলসী বাউরিক

5

IntArrayকর্মক্ষেত্র : একটিবর্গতৈরি করুনএবং মোড়ানোint[]

record Foo(IntArray ints) {
    public Foo(int... ints) { this(new IntArray(ints)); }
    public int[] getInts() { return this.ints.get(); }
}

নিখুঁত নয়, কারণ এখন আপনাকে foo.getInts()পরিবর্তে কল করতে হবে foo.ints(), তবে বাকি সমস্ত কিছুই আপনার পছন্দ মতো কাজ করে।

public final class IntArray {
    private final int[] array;
    public IntArray(int[] array) {
        this.array = Objects.requireNonNull(array);
    }
    public int[] get() {
        return this.array;
    }
    @Override
    public int hashCode() {
        return Arrays.hashCode(this.array);
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null || getClass() != obj.getClass())
            return false;
        IntArray that = (IntArray) obj;
        return Arrays.equals(this.array, that.array);
    }
    @Override
    public String toString() {
        return Arrays.toString(this.array);
    }
}

আউটপুট

Foo[ints=[1, 2]]
true
true
true

1
এমন ক্ষেত্রে ক্লাস ব্যবহার করতে বলার সমতুল্য নয় এবং রেকর্ডও নয়?
নমন

1
@ নমন মোটেও নয়, কারণ আপনার recordক্ষেত্রে অনেকগুলি ক্ষেত্র থাকতে পারে এবং কেবল অ্যারে ফিল্ডগুলি এর মতো মোড়ানো থাকে।
Andreas

আপনি পুনঃব্যবহারযোগ্যতার দিক থেকে আপনি যে বিষয়টিটি তৈরি করতে চাইছেন তা আমি পেয়েছি, তবে তারপরে এখানে অন্তর্নির্মিত শ্রেণি রয়েছে Listযা এখানে প্রস্তাবিত হিসাবে সমাধানের সন্ধান করতে পারে এমন ধরণের মোড়ক সরবরাহ করে। বা আপনি কি বিবেচনা করেন যে এই ধরনের ব্যবহারের ক্ষেত্রে ওভারহেড হতে পারে?
নমন

3
@ نعمান আপনি যদি কোনও সঞ্চয় করতে চান int[]তবে List<Integer>কমপক্ষে দুটি কারণে একটি একই হয় না: 1) তালিকায় অনেক বেশি স্মৃতি ব্যবহৃত হয় এবং 2) তাদের মধ্যে কোনও অন্তর্নির্মিত রূপান্তর নেই। Integer[]Fair List<Integer>মোটামুটি সহজ ( toArray(...)এবং Arrays.asList(...)), তবে int[]more List<Integer>আরও বেশি কাজ নেয়, এবং রূপান্তর করতে সময় লাগে, সুতরাং এটি এমন কিছু যা আপনি সর্বদা করতে চান না। যদি আপনার একটি থাকে int[]এবং এটি একটি রেকর্ডে সংরক্ষণ করতে চান (অন্য স্টাফ সহ, অন্যথায় কেন একটি রেকর্ড ব্যবহার করুন), এবং এটি হিসাবে এটি প্রয়োজন int[], তারপরে আপনার যতবার প্রয়োজন তা রূপান্তর করা ভুল।
আন্দ্রেস

সত্যিই ভাল পয়েন্ট। আমি যদিও যদি আপনি অনুমতি nitpicking জিজ্ঞাসা পারে কি সুবিধা আমরা এখনও সঙ্গে দেখতে পাচ্ছ Arrays.equals, Arrays.toStringওভার Listযখন প্রতিস্থাপন ব্যবহৃত বাস্তবায়ন int[]হিসাবে অন্যান্য উত্তরে সুপারিশ করেছে। (ধরে নিচ্ছি এই উভয়ই যেকোন উপায়ে কাজ করা হয়েছে))
নামান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.