ජාවා හි සාමාන්‍ය අරාවක් නිර්මාණය කරන්නේ කෙසේද?


1103

ජාවා ජනක විද්‍යාව ක්‍රියාත්මක කිරීම නිසා ඔබට මෙවැනි කේතයක් තිබිය නොහැක:

public class GenSet<E> {
    private E a[];

    public GenSet() {
        a = new E[INITIAL_ARRAY_LENGTH]; // error: generic array creation
    }
}

වර්ගයේ ආරක්ෂාව පවත්වා ගනිමින් මෙය ක්‍රියාත්මක කරන්නේ කෙසේද?

ජාවා සංසදවල මෙවැනි විසඳුමක් මම දුටුවෙමි:

import java.lang.reflect.Array;

class Stack<T> {
    public Stack(Class<T> clazz, int capacity) {
        array = (T[])Array.newInstance(clazz, capacity);
    }

    private final T[] array;
}

නමුත් මට ඇත්තටම සිදුවන්නේ කුමක්ද යන්න ලැබෙන්නේ නැත.


14
ඔයාට ඇත්තටම අවශ්ය මෙතන රැසක් භාවිතා කිරීමට? එකතුවක් භාවිතා කිරීම ගැන කුමක් කිව හැකිද?
matt b

12
ඔව්, මෙම ගැටළුව සඳහා එකතු කිරීම් වඩාත් අලංකාර යැයි මම සිතමි. නමුත් මෙය පන්ති පැවරුමක් සඳහා වන අතර ඒවා අවශ්‍ය වේ :(
tatsuhirosatou

3
මට මෙහි පරාවර්තනයක් අවශ්‍ය වන්නේ මන්දැයි මට තේරෙන්නේ නැත. ජාවා ව්‍යාකරණ අමුතුයි: නව java.util.HashMap <string, string> [10] වලංගු නොවේ. නව java.util.HashMap <දිගු, දිගු> (10) වලංගු නොවේ. නව දිගු [] [10] වලංගු නොවේ, නව දිගු [10] [] වලංගු වේ. එමඟින් ජාවා වැඩසටහන ලිවිය හැකි වැඩසටහනක් ලිවීම වඩාත් අපහසු වේ.
ලෝකඩ මිනිසා

Answers:


709

මට නැවත ප්‍රශ්නයක් ඇසීමට සිදුවේ: ඔබේ GenSet"පරීක්ෂා කර" හෝ "පරීක්ෂා නොකළ" ද? ඒ කියන්නේ මොකද්ද?

  • පරීක්ෂා කර ඇත : ශක්තිමත් ටයිප් කිරීම . GenSetඑහි අඩංගු වන්නේ කුමන වර්ගයේ වස්තූන් දැයි පැහැදිලිව දනී (එනම් එහි ඉදිකිරීම්කරු පැහැදිලිවම Class<E>තර්කයක් සමඟ කැඳවනු ලැබූ අතර , ඒවා වර්ග නොවන තර්ක සම්මත කළ විට ක්‍රමවේදයන් ව්‍යතිරේකයක් දමනු ඇත E. බලන්න Collections.checkedCollection.

    -> එවැනි අවස්ථාවක, ඔබ ලිවිය යුත්තේ:

    public class GenSet<E> {
    
        private E[] a;
    
        public GenSet(Class<E> c, int s) {
            // Use Array native method to create array
            // of a type only known at run time
            @SuppressWarnings("unchecked")
            final E[] a = (E[]) Array.newInstance(c, s);
            this.a = a;
        }
    
        E get(int i) {
            return a[i];
        }
    }
    
  • පරීක්ෂා නොකළ : දුර්වල ටයිප් කිරීම . තර්කයක් ලෙස සම්මත කරන ලද ඕනෑම වස්තුවක් මත සත්‍ය වශයෙන්ම වර්ගීකරණයක් සිදු නොකෙරේ.

    -> එවැනි අවස්ථාවක ඔබ ලිවිය යුතුය

    public class GenSet<E> {
    
        private Object[] a;
    
        public GenSet(int s) {
            a = new Object[s];
        }
    
        E get(int i) {
            @SuppressWarnings("unchecked")
            final E e = (E) a[i];
            return e;
        }
    }
    

    අරාවෙහි සංරචක වර්ගය පරාමිතිය මකා දැමීම විය යුතු බව සලකන්න :

    public class GenSet<E extends Foo> { // E has an upper bound of Foo
    
        private Foo[] a; // E erases to Foo, so use Foo[]
    
        public GenSet(int s) {
            a = new Foo[s];
        }
    
        ...
    }
    

මේ සියල්ලේ ප්‍රති results ලය වන්නේ ජාවා හි දන්නා සහ හිතාමතාම ජනක විද්‍යාවේ දුර්වලතාවයකි: එය ක්‍රියාත්මක කරනු ලැබුවේ මකාදැමීමෙනි, එබැවින් “සාමාන්‍ය” පංති ක්‍රියාත්මක වන වේලාවේදී කුමන ආකාරයේ තර්කයක් නිර්මාණය කළේදැයි නොදනී. කිසියම් පැහැදිලි යාන්ත්‍රණයක් (වර්ගය පරීක්ෂා කිරීම) ක්‍රියාත්මක නොකරන්නේ නම් ආරක්ෂාව.


7
කාර්ය සාධනය අනුව හොඳම විකල්පය කුමක්ද? මට බොහෝ විට මෙම අරාවෙන් මූලද්‍රව්‍ය ලබා ගත යුතුය (ලූපයක් තුළ). එබැවින් එකතුවක් මන්දගාමී වේ, නමුත් මේ දෙකෙන් වේගවත්ම දේ කුමක්ද?
user1111929

3
සාමාන්‍ය වර්ගය මායිම් නම්, පසුබිම් අරාව මායිම් වර්ගයට අයත් විය යුතුය.
මොර්දෙකයි

5
A ආරොන් ඩිගුල්ලා එය පැහැදිලි කිරීම සඳහා එය පැවරුමක් නොව දේශීය විචල්‍යයක් ආරම්භ කිරීමයි. ඔබට ප්‍රකාශනයක් / ප්‍රකාශයක් විවරණය කළ නොහැක.
kennytm

1
Ark වර්කාන් පන්ති ක්‍රියාත්මක කිරීමේදී මෙම අරා ප්‍රමාණය වෙනස් කිරීමට ක්‍රමයක් තිබේද? උදාහරණයක් ලෙස මට ArrayList වැනි පිටාර ගැලීමෙන් පසු ප්‍රමාණය වෙනස් කිරීමට අවශ්‍ය නම්. Object[] EMPTY_ELEMENTDATA = {}ගබඩා කිරීම සඳහා ඔවුන් සතුව ඇති අරා ලැයිස්තු ක්‍රියාත්මක කිරීම මම සොයා බැලුවෙමි . ජනක විද්‍යාව භාවිතා කරන වර්ගය නොදැන ප්‍රමාණය වෙනස් කිරීමට මට මෙම යාන්ත්‍රණය භාවිතා කළ හැකිද?
ජර්මන් මෑන්

2
සාමාන්‍ය වර්ගයක් සහිත ක්‍රමවේදයක් සෑදීමට කැමති අය සඳහා (මෙය මා සොයන දෙයයි), මෙය භාවිතා කරන්න:public void <T> T[] newArray(Class<T> type, int length) { ... }
ඩැනියෙල් ක්විස්ට්

229

ඔබට මෙය කරන්න පුළුවන්:

E[] arr = (E[])new Object[INITIAL_ARRAY_LENGTH];

Effective ලදායී ජාවා හි සාමාන්‍ය එකතුවක් ක්‍රියාත්මක කිරීමේ යෝජිත ක්‍රමවලින් එකක් මෙයයි ; අයිතමය 26 . වර්ග දෝෂ නොමැත, නැවත නැවත අරාව දැමිය යුතු නැත. කෙසේ වෙතත් මෙය අනතුරු ඇඟවීමක් අවුලුවන බැවින් එය අනතුරුදායක විය හැකි අතර එය ප්‍රවේශමෙන් භාවිතා කළ යුතුය. අදහස් වල විස්තර කර ඇති පරිදි, මෙය Object[]දැන් අපගේ E[]වර්ගය ලෙස වෙස්වලාගෙන ඇති අතර අනාරක්ෂිත ලෙස ClassCastExceptionභාවිතා කරන්නේ නම් අනපේක්ෂිත දෝෂ හෝ ඒවා ඇති විය හැකිය .

රීතියක් ලෙස, වාත්තු අරාව අභ්‍යන්තරව භාවිතා කරන තාක් කල් මෙම හැසිරීම ආරක්ෂිත වේ (උදා: දත්ත ව්‍යුහයකට පිටුබලය දීම), සහ සේවාදායක කේතයට ආපසු හෝ නිරාවරණය නොවීම. ඔබට සාමාන්‍ය වර්ගයක පෙළක් වෙනත් කේතයකට ආපසු යැවීමට අවශ්‍ය නම්, Arrayඔබ සඳහන් කරන පරාවර්තන පන්තිය යනු නිවැරදි මාර්ගයයි.


හැකි සෑම තැනකම, ඔබ Listජනක විද්‍යාව භාවිතා කරන්නේ නම්, අරා වලට වඩා s සමඟ වැඩ කිරීමට ඔබට වඩා ප්‍රීතිමත් කාලයක් ලැබෙනු ඇති බව සඳහන් කිරීම වටී . නිසැකවම සමහර විට ඔබට විකල්පයක් නැත, නමුත් එකතු කිරීමේ රාමුව භාවිතා කිරීම වඩා ශක්තිමත් ය.


47
String[] s=b;ඉහත test()ක්‍රමය වැනි අරාව ඕනෑම ආකාරයක ටයිප් කළ අරාවක් ලෙස සලකන්නේ නම් මෙය ක්‍රියා නොකරනු ඇත . එයට හේතුව E හි අරාව සැබවින්ම නොවන නිසා එය වස්තුවයි []. ඔබට අවශ්‍ය නම් මෙය වැදගත් වේ, උදා: List<String>[]ඔබට ඒ සඳහා භාවිතා කළ නොහැක Object[], ඔබට List[]විශේෂයෙන් තිබිය යුතුය . පරාවර්තනය කළ පංතිය <?> අරාව නිර්මාණය කිරීම භාවිතා කිරීමට අවශ්‍ය වන්නේ එබැවිනි.
ලෝරන්ස් ඩොල්

8
කෙළවරේ-අවස්ථාවේදී / ප්රශ්නය, උදාහරණයක් ලෙස, ඔබට කරන්න ඕන නම් වේ public E[] toArray() { return (E[])internalArray.clone(); }විට internalArrayලෙස ටයිප් ඇත E[], එම නිසා ඇත්තටම යනු Object[]. මෙය ක්‍රියාත්මක වන වේලාවේදී ටයිප්-කාස්ට් ව්‍යතිරේකයක් සමඟ අසමත් වේ, මන්ද යත් Object[], ඕනෑම ආකාරයක Eසිදුවීමකට අනුයුක්ත කළ නොහැකි බැවිනි.
ලෝරන්ස් ඩොල්

17
මූලික වශයෙන්, ඔබ අරාව ආපසු නොඑන තාක් හෝ එය පසුකර නොයන තාක් කල් හෝ කිසියම් වර්ගයක පෙළක් අවශ්‍ය වන පන්තියෙන් පිටත යම් ස්ථානයක ගබඩා නොකරනු ඇත. ඔබ පන්තිය තුළ සිටින තාක් කල් ඔබ හොඳ නිසා ඊ මකා දමා ඇත. එය "භයානක" නිසා ඔබ එය හෝ යමක් ආපසු ලබා දීමට උත්සාහ කරන්නේ නම්, එය අනාරක්ෂිත බවට ඔබට අනතුරු ඇඟවීමක් නොලැබේ. නමුත් ඔබ පරිස්සම් නම් එය ක්‍රියාත්මක වේ.
newacct

3
එය තරමක් ආරක්ෂිතයි. දී E[] b = (E[])new Object[1];ඔබ පැහැදිලිව නිර්මාණය මාලාවක් එකම යොමු වන බව දකින්න පුළුවන් bසහ වර්ගය බව bකියන්නේ E[]. එම නිසා ඔබ වෙනත් වර්ගයක වෙනස් විචල්‍යයක් හරහා එකම අරාවකට අහම්බෙන් ප්‍රවේශ වීමේ අවදානමක් නොමැත. ඒ වෙනුවට, ඔබ එසේ කර ඇත්නම්, Object[] a = new Object[1]; E[]b = (E[])a; ඔබ භාවිතා කරන ආකාරය ගැන ඔබ ව්‍යාකූල විය යුතුය a.
ආරොන් මැක්ඩේඩ්

5
අවම වශයෙන් ජාවා 1.6 හි, මෙය අනතුරු ඇඟවීමක් කරයි: "වස්තුව [] සිට ටී [] දක්වා
පරීක්ෂා නොකළ වාත්තු කිරීම

61

වර්ගයේ ආරක්ෂාව ආරක්ෂා කරන අතරම ඔබ සොයන ආකාරයේ වර්ගයක් ලබා ගැනීම සඳහා ජනක විද්‍යාව භාවිතා කරන්නේ කෙසේද යන්න මෙන්න (අනෙක් පිළිතුරු වලට වඩා වෙනස්ව, එය ඔබට නැවත Objectඅරාවක් ලබා දෙනු ඇත හෝ සම්පාදනය කරන අවස්ථාවේ අනතුරු ඇඟවීම් ලබා දෙනු ඇත):

import java.lang.reflect.Array;  

public class GenSet<E> {  
    private E[] a;  

    public GenSet(Class<E[]> clazz, int length) {  
        a = clazz.cast(Array.newInstance(clazz.getComponentType(), length));  
    }  

    public static void main(String[] args) {  
        GenSet<String> foo = new GenSet<String>(String[].class, 1);  
        String[] bar = foo.a;  
        foo.a[0] = "xyzzy";  
        String baz = foo.a[0];  
    }  
}

එය අනතුරු ඇඟවීමකින් තොරව සම්පාදනය වන අතර, ඔබට පෙනෙන පරිදි main, ඔබ කුමන වර්ගයක නිදසුනක් GenSetලෙස ප්‍රකාශ කළත් , ඔබට aඑම වර්ගයේ අරාවකට අනුයුක්ත කළ හැකි අතර, ඔබට එම වර්ගයේ aවිචල්‍යයකට මූලද්‍රව්‍යයක් පැවරිය හැකිය , එනම් අරාව සහ අරාවෙහි අගයන් නිවැරදි වර්ගයට අයත් වේ.

ජාවා නිබන්ධනවල සාකච්ඡා කර ඇති පරිදි පන්ති වචනාර්ථය ධාවන කාල ටෝකන ලෙස භාවිතා කිරීමෙන් එය ක්‍රියාත්මක වේ. පංති සාක්ෂරතා සම්පාදකයා විසින් උදාහරණ ලෙස සලකනු ලැබේ java.lang.Class. එකක් භාවිතා කිරීමට, සමඟ පන්තියක නම අනුගමනය කරන්න .class. එබැවින්, පන්තිය නියෝජනය String.classකරන Classවස්තුවක් ලෙස ක්‍රියා කරයි String. මෙය අතුරුමුහුණත්, එනූම්ස්, ඕනෑම මාන අරා (උදා String[].class), ප්‍රාථමික (උදා int.class) සහ මූල පදය void(එනම් void.class) සඳහා ද ක්‍රියා කරයි.

Classම Generic බලපත්රය යටතේ අවසර ලබා ඇත වේ (ලෙස ප්රකාශයට පත් Class<T>කොහේද, Tබව වර්ගය සඳහා කි්රයා Classවර්ගය තේරුම වන්නේ, වස්තුවක් නියෝජනය), String.classයනු Class<String>.

ඒ නිසා, ඔබ වෙනුවෙන් ඉදිකිරීමටත් අයැදින GenSet, ඔබ රැසක් නියෝජනය කරන පළමු වාදය සඳහා පන්ති ප්රායෝගික සමත් GenSetඋදාහරණයක් ප්රකාශිත වර්ගය (උදා: String[].classසඳහා GenSet<String>). වර්ග විචල්‍යයන් සඳහා ප්‍රාථමිකයන් භාවිතා කළ නොහැකි බැවින් ඔබට ප්‍රාථමික පෙළක් ලබා ගත නොහැකි බව සලකන්න.

ඉදිකිරීම්කරු තුළ, ක්‍රමවේදය ඇමතීමෙන්, castසම්මත කරන ලද Objectතර්කය Class, ක්‍රමය හැඳින්වූ වස්තුව නියෝජනය කරන පන්තියට යවයි . පළමු තර්කය ලෙස සම්මත කරන ලද වස්තුව නියෝජනය කරන වර්ගයේ අරාව ලෙසත්, දෙවන තර්කය ලෙස සම්මත කළ නිශ්චිතව දක්වා ඇති දිගටත් newInstance, java.lang.reflect.Arrayප්‍රතිලාභවල ස්ථිතික ක්‍රමය ඇමතීම . මෙම ක්රමය ඉල්ලා ඇති නැවත විසින් නියෝජනය අරාව යන සංරචකය වර්ගය නියෝජනය වස්තුව (උදා: කරන ක්රමය ලෙස හැඳින්වූ වස්තුව සඳහා , නම්, වස්තුව රැසක් නියෝජනය වන්නේ නැත).ObjectClassintgetComponentTypeClassClassString.classString[].classnullClass

එම අවසාන වාක්‍යය සම්පූර්ණයෙන්ම නිවැරදි නොවේ. ඇමතීමෙන් පන්තිය නියෝජනය String[].class.getComponentType()කරන Classවස්තුවක් ආපසු ලබා දෙයි String, නමුත් එහි වර්ගය එසේ Class<?>නොවේ Class<String>, ඒ නිසා ඔබට පහත සඳහන් දේ වැනි දෙයක් කළ නොහැක.

String foo = String[].class.getComponentType().cast("bar"); // won't compile

වස්තුවක් Classආපසු ලබා දෙන සෑම ක්‍රමයක් සඳහාම Classඑයම වේ.

මෙම පිළිතුර පිළිබඳව ජොකිම් සෝවර් කළ ප්‍රකාශය සම්බන්ධයෙන් (ඒ පිළිබඳව මා ගැනම අදහස් දැක්වීමට තරම් කීර්තියක් මා සතුව නැත), වාත්තු කිරීම භාවිතා කිරීම පිළිබඳ උදාහරණය T[]අනතුරු ඇඟවීමක් වනු ඇත, මන්ද එම අවස්ථාවේ දී සම්පාදකයාට වර්ගයේ ආරක්ෂාව සහතික කළ නොහැකි බැවිනි.


ඉන්ගෝගේ අදහස් සම්බන්ධයෙන් සංස්කරණය කරන්න:

public static <T> T[] newArray(Class<T[]> type, int size) {
   return type.cast(Array.newInstance(type.getComponentType(), size));
}

5
මෙය නිෂ් less ල ය, එය නව නූල් ලිවීමට සංකීර්ණ ක්‍රමයක් පමණි [...]. නමුත් ඇත්ත වශයෙන්ම අවශ්‍ය වන්නේ පොදු ස්ථිතික <T> ටී [] නව අරේ (int ප්‍රමාණය) {...} වැනි දෙයක් වන අතර මෙය ජාවා නොයාර් හි නොපවතින අතර එය පරාවර්තනය සමඟ අනුකරණය කළ හැකිය - හේතුව එය පිළිබඳ තොරතුරු සාමාන්‍ය වර්ගයක් ක්ෂණිකව ක්‍රියාත්මක වන විට ක්‍රියාත්මක වේ.
ඉන්ගෝ

4
එන්ගෝ ඔබ මොනවා ගැනද කතා කරන්නේ? ඕනෑම වර්ගයක පෙළක් නිර්මාණය කිරීමට මගේ කේතය භාවිතා කළ හැකිය.
gdejohn

3
Har චාර්ලාටන්: ෂුවර්, නමුත් අළුත් []. ප්‍රශ්නය වන්නේ: වර්ගය සහ කවදා දන්නේ කවුද යන්නයි. එමනිසා, ඔබ සතුව ඇත්තේ සාමාන්‍ය වර්ගයක් නම්, ඔබට බැහැ.
ඉන්ගෝ

2
මම ඒ ගැන සැක කරන්නේ නැහැ. කාරණය නම්, සාමාන්‍ය වර්ගයේ X සඳහා ධාවන වේලාවේදී ඔබට පන්ති වස්තුවක් නොලැබේ.
ඉන්ගෝ

2
පාහේ. මෙය නව [] සමඟ ලබා ගත හැකි දේට වඩා වැඩි බව මම පිළිගනිමි. ප්රායෝගිකව, මෙය සෑම විටම පාහේ කාර්යය ඉටු කරනු ඇත. කෙසේ වෙතත්, නිදසුනක් ලෙස, ඊ සමඟ පරාමිතිගත කරන ලද බහාලුම් පන්තියක් ලිවීමට තවමත් නොහැකි අතර එය ඊ [] සිට අරේ () දක්වා ක්‍රමයක් ඇති අතර එය සත්‍ය ඊ [අරා] ලබා දෙයි. ඔබේ කේතය යෙදිය හැක්කේ අවම වශයෙන් එක් ඊ-වස්තුවක් එකතුවේ ඇති විට පමණි. එබැවින් පොදු විසඳුමක් කළ නොහැකි ය.
ඉන්ගෝ

42

ආරක්ෂිත ටයිප් කරන එකම පිළිතුර මෙයයි

E[] a;

a = newArray(size);

@SafeVarargs
static <E> E[] newArray(int length, E... array)
{
    return Arrays.copyOf(array, length);
}

මට එය සොයා බැලීමට සිදු විය, නමුත් ඔව්, දෙවන "දිග" තර්කය Arrays#copyOf()පළමු තර්කය ලෙස සපයා ඇති අරාවේ දිගට වඩා ස්වාධීන වේ. එය වෙත ඇමතුම් වියදම ගෙවීමට නැහැ නමුත්, දක්ෂ වේ Math#min()හා System#arrayCopy()දැඩි මෙම කටයුත්ත ඉටු කිරීම සඳහා අවශ්ය වේ වත් වන. docs.oracle.com/javase/7/docs/api/java/util/…
seh

8
Eවර්ග විචල්‍යයක් නම් මෙය ක්‍රියා නොකරයි . වර්රාග්ස් වර්ග විචල්‍යයක් වන Eවිට මකාදැමීමේ පෙළක් නිර්මාණය කරයි E, එය වඩා වෙනස් නොවේ (E[])new Object[n]. කරුණාකර http://ideone.com/T8xF91 බලන්න . එය කිසි ලෙසකින්වත් වෙනත් ඕනෑම පිළිතුර වඩා වර්ගය ආරක්ෂිත.
රේඩියෝඩෙෆ්

1
Adi රේඩියෝඩෙෆ් - විසඳුම සම්පාදනය කරන වේලාවේදී ආරක්ෂිත වේ. මකාදැමීම හරියටම භාෂා පිරිවිතරයේ කොටසක් නොවන බව සලකන්න; අනාගතයේ දී අපට පූර්ණ ප්‍රතිසංස්කරණයක් ලබා ගත හැකි වන පරිදි පිරිවිතරයන් ප්‍රවේශමෙන් ලියා ඇත - එවිට මෙම විසඳුම වෙනත් විසඳුම් මෙන් නොව ධාවන වේලාවේදී ද පරිපූර්ණ ලෙස ක්‍රියා කරනු ඇත.
ෂොංයු

Ad රේඩියෝඩෙෆ් - සාමාන්‍ය අරා නිර්මාණය තහනම් කිරීම හොඳ අදහසක් ද යන්න විවාදාත්මක ය. නොසලකා, භාෂාව පසුපස දොරක් තබයි - වර්රාග්ට සාමාන්‍ය අරා නිර්මාණය අවශ්‍ය වේ. එය භාෂාවට අවසර දී ඇති ආකාරයටම හොඳයි new E[]. ඔබේ උදාහරණයේ ඔබ පෙන්වා ඇති ගැටළුව සාමාන්‍ය මකාදැමීමේ ගැටළුවක් වන අතර මෙම ප්‍රශ්නයට සහ මෙම පිළිතුරට අනන්‍ය නොවේ.
ෂොංයු

2
Ad රේඩියෝඩෙෆ් - වෙනස්කම් කිහිපයක් තිබේ. මෙම විසඳුමේ නිරවද්‍යතාවය සම්පාදකයා විසින් පරීක්ෂා කරනු ලැබේ; එය බලහත්කාරයෙන් වාත්තු කිරීම පිළිබඳ මානව තර්කනය මත රඳා නොපවතී. මෙම විශේෂිත ගැටළුව සඳහා වෙනස සැලකිය යුතු නොවේ. සමහර අය ටිකක් විසිතුරු වීමට කැමතියි, එපමණයි. OP හි වචන වලින් කිසිවෙකු නොමඟ යවනු ලැබුවහොත්, එය ඔබගේ අදහස් සහ මගේ මගින් පැහැදිලි වේ.
ෂොංයු

33

වැඩි මානයන් දක්වා විස්තාරණය කිරීම සඳහා, []'සහ මානයන්හි පරාමිතීන් එක් කරන්න newInstance()( Tවර්ග පරාමිතියකි, clsa Class<T>, d1හරහා d5පූර්ණ සංඛ්‍යා වේ):

T[] array = (T[])Array.newInstance(cls, d1);
T[][] array = (T[][])Array.newInstance(cls, d1, d2);
T[][][] array = (T[][][])Array.newInstance(cls, d1, d2, d3);
T[][][][] array = (T[][][][])Array.newInstance(cls, d1, d2, d3, d4);
T[][][][][] array = (T[][][][][])Array.newInstance(cls, d1, d2, d3, d4, d5);

විස්තර Array.newInstance()සඳහා බලන්න.


4
+1 මෙම ලිපියේ අනුපිටපත් ලෙස වසා දැමිය හැකි බහු-මාන අරාව නිර්මාණය පිළිබඳ ප්‍රශ්න තිබේ - නමුත් කිසිදු පිළිතුරක් ඒ සඳහා නිශ්චිතව ආමන්ත්‍රණය කර නැත.
පෝල් බෙලෝරා

1
Ord ජෝර්දාන් සී; එය ආත්මයෙන් එක සමාන වුවත් stackoverflow.com/a/5671304/616460 ; මම හෙට හැසිරවිය හැකි හොඳම ක්‍රමය ගැන සිතමි. මට නිදිමතයි.
ජේසන් සී

14

ජාවා 8 හි, අපට ලැම්බඩා හෝ ක්‍රම යොමුව භාවිතා කරමින් යම් ආකාරයක සාමාන්‍ය අරාව නිර්මාණය කළ හැකිය. මෙය පරාවර්තක ප්‍රවේශයට සමාන වේ (එය a පසු කරයි Class), නමුත් මෙහිදී අපි පරාවර්තනය භාවිතා නොකරමු.

@FunctionalInterface
interface ArraySupplier<E> {
    E[] get(int length);
}

class GenericSet<E> {
    private final ArraySupplier<E> supplier;
    private E[] array;

    GenericSet(ArraySupplier<E> supplier) {
        this.supplier = supplier;
        this.array    = supplier.get(10);
    }

    public static void main(String[] args) {
        GenericSet<String> ofString =
            new GenericSet<>(String[]::new);
        GenericSet<Double> ofDouble =
            new GenericSet<>(Double[]::new);
    }
}

උදාහරණයක් ලෙස, මෙය භාවිතා කරන්නේ <A> A[] Stream.toArray(IntFunction<A[]>).

මෙය නිර්නාමික පංති භාවිතයෙන් ජාවා 8 ට පෙර කළ හැකි නමුත් එය වඩාත් කරදරකාරී ය.


මේ සඳහා ඔබට විශේෂ අතුරු මුහුණතක් අවශ්‍ය නොවේ ArraySupplier, ඔබට ඉදිකිරීම්කරු ලෙස ප්‍රකාශ කළ හැකි GenSet(Supplier<E[]> supplier) { ...අතර ඔබට ඇති එකම රේඛාවෙන් එය අමතන්න.
ලී

4
ILii මගේ ආදර්ශයට සමාන වීමට නම් එය එසේ වනු ඇත IntFunction<E[]>, නමුත් ඔව් එය සත්‍යයකි.
රේඩියෝඩෙෆ්

13

මෙය Java ලදායී ජාවා, 2 වන සංස්කරණය , 25 වන අයිතමයේ 5 වන පරිච්ඡේදයේ (ජනක විද්‍යාව) ආවරණය කර ඇත ... අරා සඳහා ලැයිස්තු මනාප

ඔබගේ කේතය ක්‍රියා නොකරනු ඇත, එය පරීක්ෂා නොකළ අනතුරු ඇඟවීමක් ජනනය කළද (පහත දැක්වෙන විවරණයෙන් ඔබට එය යටපත් කළ හැකිය:

@SuppressWarnings({"unchecked"})

කෙසේ වෙතත්, අරාව වෙනුවට ලැයිස්තුවක් භාවිතා කිරීම වඩා හොඳය.

OpenJDK ව්‍යාපෘති අඩවියේ මෙම දෝෂය / විශේෂාංගය පිළිබඳ සිත්ගන්නා සංවාදයක් ඇත .


8

පංති තර්කය ඉදිකිරීම්කරු වෙත යැවීමට ඔබට අවශ්‍ය නැත. මේක උත්සාහ කරන්න.

public class GenSet<T> {
    private final T[] array;
    @SuppressWarnings("unchecked")
    public GenSet(int capacity, T... dummy) {
        if (dummy.length > 0)
            throw new IllegalArgumentException(
              "Do not provide values for dummy argument.");
        Class<?> c = dummy.getClass().getComponentType();
        array = (T[])Array.newInstance(c, capacity);
    }
    @Override
    public String toString() {
        return "GenSet of " + array.getClass().getComponentType().getName()
            + "[" + array.length + "]";
    }
}

සහ

GenSet<Integer> intSet = new GenSet<>(3);
System.out.println(intSet);
System.out.println(new GenSet<String>(2));

ප්‍රති result ලය:

GenSet of java.lang.Integer[3]
GenSet of java.lang.String[2]

7

ජාවා ජනක විද්‍යාව ක්‍රියාත්මක වන්නේ සම්පාදනය කරන වේලාවේ වර්ග පරීක්ෂා කිරීමෙන් සහ සුදුසු කැස්ට් ඇතුළු කිරීමෙන් ය, නමුත් සම්පාදනය කරන ලද ලිපිගොනු වල වර්ග මකා දමයි . මෙමඟින් ජනක පුස්තකාල තේරුම් ගත නොහැකි කේතයක් මඟින් භාවිතා කළ හැකිය (එය හිතාමතාම සැලසුම් තීරණයක් විය) නමුත් එයින් අදහස් කරන්නේ ක්‍රියාත්මක වන වේලාවේ වර්ගය කුමක්දැයි ඔබට සාමාන්‍යයෙන් සොයාගත නොහැකි බවයි.

රාජ්ය Stack(Class<T> clazz,int capacity)ඉදිකිරීමටත් පන්ති තොරතුරු, ඉන් අදහස් වන්නේ, ලකුණු අවස්ථාවේ දී පංති වස්තුව සම්මත කිරීමට ඔබ අවශ්ය වේ එය අවශ්ය බව කේතය කිරීමට ක්රියාත්මක වීමේදී එහි දක්වා එළඹිය නොහැක. හා Class<T>ආකෘති පත්රය සම්පාදකවරයා ඔබ සමත් පන්ති වස්තුව අදවන ටී උපපංතිය, ටී ක superclass නොවේ වර්ගයක් ටී සඳහා පන්තියේ වස්තුව වේ, නමුත් හරියටම ටී බව පරීක්ෂා කරන බව අදහස්

මෙයින් අදහස් කරන්නේ ඔබට ඔබේ ඉදිකිරීම්කරු තුළ සුදුසු වර්ගයේ අරාව වස්තුවක් නිර්මාණය කළ හැකි බවයි, එයින් අදහස් වන්නේ ඔබ ඔබේ එකතුවෙහි ගබඩා කරන වස්තූන්ගේ වර්ගය එකතු කිරීමට එකතු කරන මොහොතේදී ඒවායේ වර්ග පරීක්ෂා කරනු ඇති බවයි.


6

හායි, ත්‍රෙඩ් එක මැරුණත්, මම මේ ගැන ඔබේ අවධානය යොමු කරන්න කැමතියි:

සම්පාදනය කරන වේලාවේදී වර්ග පරීක්ෂා කිරීම සඳහා ජනක විද්‍යාව භාවිතා කරයි:

  • එබැවින් අරමුණ වන්නේ ඔබට අවශ්‍ය දේ පැමිණෙන්නේද යන්න පරීක්ෂා කිරීමයි.
  • ඔබ ආපසු එන්නේ පාරිභෝගිකයාට අවශ්‍ය දෙයයි.
  • මෙය පරීක්ෂා කරන්න:

රූප විස්තරය මෙහි ඇතුළත් කරන්න

ඔබ සාමාන්‍ය පන්තියක් ලියන විට යතුරු ලියනය කිරීමේ අනතුරු ඇඟවීම් ගැන කරදර නොවන්න. ඔබ එය භාවිතා කරන විට කරදර වන්න.


6

මෙම විසඳුම ගැන කුමක් කිව හැකිද?

@SafeVarargs
public static <T> T[] toGenericArray(T ... elems) {
    return elems;
}

එය ක්‍රියාත්මක වන අතර සත්‍ය වීමට තරම් සරල නැත. අඩුපාඩුවක් තිබේද?


3
පිළිවෙලට, නමුත් ක්‍රියාත්මක වන්නේ ඔබ එය 'අතින්' ලෙස හැඳින්වුවහොත් පමණි, එනම් මූලද්‍රව්‍ය තනි තනිව සම්මත කරන්න. ඔබට නව අවස්ථාවක් නිර්මාණය කළ නොහැකි නම්, ඔබට ක්‍රමානුකූලව ශ්‍රිතයට T[]පිවිසිය නොහැක T[] elems. ඔබට හැකි නම්, ඔබට ශ්‍රිතය අවශ්‍ය නොවනු ඇත.
ඕර්ලේඩ්

5

මෙම කේතය දෙසද බලන්න:

public static <T> T[] toArray(final List<T> obj) {
    if (obj == null || obj.isEmpty()) {
        return null;
    }
    final T t = obj.get(0);
    final T[] res = (T[]) Array.newInstance(t.getClass(), obj.size());
    for (int i = 0; i < obj.size(); i++) {
        res[i] = obj.get(i);
    }
    return res;
}

එය ඕනෑම ආකාරයක වස්තුවක ලැයිස්තුවක් එකම වර්ගයේ අරාවකට පරිවර්තනය කරයි.


ඔව්, ඔබ ආපසු එන්නේ අපේක්ෂිත හිස් අරාව නොවේ. එය ඔබට කළ හැකි හොඳම දේ මිස පරමාදර්ශී නොවේ.
කෙවින් කොක්ස්

නම්, මෙය ද අසමත් හැකි Listඑය වස්තුව වර්ග එකකට වැඩි සංඛ්යාවක් ඇති උදා: toArray(Arrays.asList("abc", new Object()))විසි ඇත ArrayStoreException.
රේඩියෝඩෙෆ්

මම මෙහි ඉවත් කළ අනුවාදයක් භාවිතා කළෙමි; පළමුවෙන්ම මට එය භාවිතා කිරීමට හැකි විය, පිළිගත හැකි වුවත් මම ඊට වඩා සම්බන්ධ විසඳුම් කිහිපයක් උත්සාහ නොකළෙමි. එක් එක් දර්ශකයට සමාන අගයක් අවශ්‍ය බැවින් මම forභාවිතා කළ ලූපයක් සහ වෙනත් ඒවා වළක්වා ගැනීමට Arrays.fill(res, obj);.
bbarker

5

මට වැඩ කරන ඉක්මන් හා පහසු ක්‍රමයක් මම සොයාගෙන ඇත. මම මෙය ජාවා ජේඩීකේ 8 හි පමණක් භාවිතා කර ඇති බව සලකන්න. එය පෙර සංස්කරණ සමඟ ක්‍රියා කරයිදැයි මම නොදනිමි.

නිශ්චිත වර්ගයේ පරාමිතියක සාමාන්‍ය පෙළක් අපට ක්ෂණිකව දැක්විය නොහැකි වුවද, අපට දැනටමත් නිර්මාණය කර ඇති අරාව සාමාන්‍ය පන්ති සාදන්නෙකුට ලබා දිය හැකිය.

class GenArray <T> {
    private T theArray[]; // reference array

    // ...

    GenArray(T[] arr) {
        theArray = arr;
    }

    // Do whatever with the array...
}

දැන් ප්‍රධාන වශයෙන් අපට එවැනි අරා නිර්මාණය කළ හැකිය:

class GenArrayDemo {
    public static void main(String[] args) {
        int size = 10; // array size
        // Here we can instantiate the array of the type we want, say Character (no primitive types allowed in generics)
        Character[] ar = new Character[size];

        GenArray<Character> = new Character<>(ar); // create the generic Array

        // ...

    }
}

ඔබේ අරා සමඟ වැඩි නම්යතාවයක් සඳහා ඔබට සම්බන්ධිත ලැයිස්තුවක් භාවිතා කළ හැකිය. Java.util.ArrayList පන්තියේ ඇති අරේලිස්ට් සහ වෙනත් ක්‍රම.


4

උදාහරණය වන්නේ අරාව නිර්මාණය කිරීම සඳහා ජාවා පරාවර්තනය භාවිතා කිරීමයි. යතුරු ලියනය කිරීම ආරක්ෂිත නොවන බැවින් මෙය කිරීම සාමාන්‍යයෙන් නිර්දේශ නොකරයි. ඒ වෙනුවට, ඔබ කළ යුත්තේ අභ්‍යන්තර ලැයිස්තුවක් භාවිතා කිරීම පමණක් වන අතර අරාව කිසිසේත් වළකින්න.


13
(Array.newInstance () භාවිතා කරමින්) දෙවන උදාහරණය වන්නේ ඇත්ත typesafe දී. පංති වස්තුවේ ටී වර්ගය අරාවේ ටී සමඟ සැසඳිය යුතු නිසා මෙය කළ හැකිය. ජාවා ධාවන කාලය ජනක විද්‍යාව සඳහා ඉවතලන තොරතුරු සැපයීමට එය මූලික වශයෙන් ඔබට බල කරයි.
ජෝකිම් සෝවර්


3

සරල ස්වයංක්‍රීය පරීක්ෂණ උපයෝගීතාවයක් සඳහා සමත් වූ පංතියක් පරාවර්තකව ක්ෂණිකව තහවුරු කිරීම සඳහා මම මෙම කේත ස්නිපටය සෑදුවෙමි.

Object attributeValue = null;
try {
    if(clazz.isArray()){
        Class<?> arrayType = clazz.getComponentType();
        attributeValue = Array.newInstance(arrayType, 0);
    }
    else if(!clazz.isInterface()){
        attributeValue = BeanUtils.instantiateClass(clazz);
    }
} catch (Exception e) {
    logger.debug("Cannot instanciate \"{}\"", new Object[]{clazz});
}

මෙම කොටස සැලකිල්ලට ගන්න:

    if(clazz.isArray()){
        Class<?> arrayType = clazz.getComponentType();
        attributeValue = Array.newInstance(arrayType, 0);
    }

අරාව ආරම්භ කිරීම සඳහා Array.newInstance (අරාව පන්තිය, අරාවෙහි ප්‍රමාණය) . පන්තිය ප්‍රාථමික (int.class) සහ වස්තුව (Integer.class) යන දෙකම විය හැකිය.

බීන් යුටිල්ස් වසන්තයේ කොටසකි.


3

ඇත්ත වශයෙන්ම එසේ කිරීමට පහසුම ක්‍රමය නම්, පහත දැක්වෙන උදාහරණය මෙන් වස්තු සමූහයක් නිර්මාණය කර ඔබේ අපේක්ෂිත වර්ගයට දැමීමයි.

T[] array = (T[])new Object[SIZE];

එහිදී SIZEනියත වන අතර, Tමේ වර්ගයේ හඳුනාගැනීමේ


1

වෙනත් පුද්ගලයින් විසින් යෝජනා කරන ලද බලහත්කාරයෙන් මා වෙනුවෙන් වැඩ නොකළ අතර නීති විරෝධී වාත්තු කිරීම හැර.

කෙසේ වෙතත්, මෙම ව්‍යාජ වාත්තු කිරීම හොඳින් ක්‍රියාත්මක විය:

Item<K>[] array = new Item[SIZE];

අයිතමය යනු සාමාජිකයා අඩංගු මා විසින් අර්ථ දක්වා ඇති පන්තියකි:

private K value;

මේ ආකාරයෙන් ඔබට K වර්ගයේ පෙළක් (අයිතමයේ වටිනාකම පමණක් තිබේ නම්) හෝ පන්ති අයිතමයේ අර්ථ දැක්වීමට අවශ්‍ය ඕනෑම සාමාන්‍ය වර්ගයක් ලැබේ.


1

ඔබ පළ කළ උදාහරණයේ සිදුවන්නේ කුමක්ද යන ප්‍රශ්නයට වෙනත් කිසිවෙකු පිළිතුරු දී නොමැත.

import java.lang.reflect.Array;

class Stack<T> {
    public Stack(Class<T> clazz, int capacity) {
        array = (T[])Array.newInstance(clazz, capacity);
    }

    private final T[] array;
}

අනෙක් අය පවසා ඇති පරිදි සම්පාදනය කිරීමේදී ජනක විද්‍යාව “මකා දමනු ලැබේ”. එබැවින් ධාවන වේලාවේදී ජනකයක උදාහරණයක් එහි සංරචක වර්ගය කුමක්දැයි නොදනී. එයට හේතුව historical තිහාසික ය, සූර්යයාට අවශ්‍ය වූයේ පවතින අතුරු මුහුණත (මූලාශ්‍රය සහ ද්විමය යන දෙකම) බිඳ නොගෙන ජනකතා එකතු කිරීමට ය.

අනෙක් අතට අරා නැහැ වීමේදී සංරචක වර්ගය දන්නවා.

මෙම උදාහරණය ගැටළුව වටා ක්‍රියා කරන්නේ ඉදිකිරීම්කරු (වර්ගය දන්නා) ලෙස හඳුන්වන කේතය පන්තියට අවශ්‍ය වර්ගය පවසන පරාමිතියක් පසුකර යාමෙනි.

එබැවින් යෙදුම පන්තිය වැනි දෙයක් සමඟ ගොඩනගනු ඇත

Stack<foo> = new Stack<foo>(foo.class,50)

සංරචක වර්ගය කුමක්දැයි ඉදිකිරීම්කරු දැන් (ධාවන වේලාවේදී) දන්නා අතර පරාවර්තන API හරහා අරාව තැනීමට එම තොරතුරු භාවිතා කළ හැකිය.

Array.newInstance(clazz, capacity);

අවසාන වශයෙන් අපට ටයිප් කාස්ට් එකක් තිබේ, මන්ද යත්, ආපසු ලබා දුන් අරාව Array#newInstance()නිවැරදි වර්ගය බව අප දැන සිටියත් සම්පාදකයාට දැනගත නොහැකි බැවිනි (අප දන්නා වුවත්).

මෙම විලාසිතාව තරමක් කැත නමුත් සමහර විට එය ඕනෑම වේලාවක (අරා නිර්මාණය කිරීම, හෝ ඒවායේ සංරචක වර්ගය පිළිබඳ අවස්ථා නිර්මාණය කිරීම ආදිය) ක්‍රියාත්මක වන වේලාවේදී ඒවායේ සංරචක වර්ගය දැන ගැනීමට අවශ්‍ය සාමාන්‍ය වර්ග නිර්මාණය කිරීම සඳහා අවම නරක විසඳුම විය හැකිය.


1

මෙම ගැටලුවට යම් ආකාරයක වැඩක් මට හමු විය.

පහත පේළිය සාමාන්‍ය අරාව සෑදීමේ දෝෂයක් විසි කරයි

List<Person>[] personLists=new ArrayList<Person>()[10];

කෙසේ වෙතත් මම List<Person>වෙනම පන්තියකට සම්බන්ධ කළහොත් එය ක්‍රියාත්මක වේ.

import java.util.ArrayList;
import java.util.List;


public class PersonList {

    List<Person> people;

    public PersonList()
    {
        people=new ArrayList<Person>();
    }
}

ඔබට පුද්ගල ලැයිස්තුවේ පන්තියේ පුද්ගලයින් හෙළිදරව් කළ හැකිය. පහත දැක්වෙන රේඛාව මඟින් ඔබට List<Person>සෑම අංගයකම අරා එකක් ලබා දෙනු ඇත . වෙනත් වචන වලින් කිවහොත් List<Person>.

PersonList[] personLists=new PersonList[10];

මා වැඩ කරමින් සිටි යම් කේතයක මට මේ වගේ දෙයක් අවශ්‍ය වූ අතර එය ක්‍රියාත්මක කිරීමට මා කළේ මෙයයි. මෙතෙක් ගැටළු නොමැත.


0

ඔබට වස්තු අරාවක් සාදා එය සෑම තැනකම E වෙත දමන්න. ඔව්, එය කිරීමට එය ඉතා පිරිසිදු ක්‍රමයක් නොවන නමුත් එය අවම වශයෙන් ක්‍රියාත්මක විය යුතුය.


"අපි දිගු පිළිතුරක් සොයන්නේ යම් පැහැදිලි කිරීමක් සහ සන්දර්භයක් ලබා දෙන්න. එක පේළියක පිළිතුරක් දෙන්න එපා; ඔබේ පිළිතුර නිවැරදි වන්නේ ඇයිද යන්න පැහැදිලි ලෙස උපුටා දැක්වීම් සමඟ පැහැදිලි කරන්න. පැහැදිලි කිරීම් නොමැතිව පිළිතුරු ඉවත් කළ හැකිය."
gparyani

නමුත් සමහර අවස්ථාවලදී ඔබේ සාමාන්‍ය පන්තියට සංසන්දනාත්මක අතුරු මුහුණතක් ක්‍රියාත්මක කිරීමට අවශ්‍ය නම් එය ක්‍රියා නොකරයි.
RamPrasadBismil

අවුරුදු හතකට පෙර සාදරයෙන් පිළිගනිමු, මම සිතමි.
Esko

1
ඔබ සාමාන්‍ය කේතයෙන් අරාව සාමාන්‍ය නොවන ඇමතුමකට ආපසු ලබා දීමට උත්සාහ කළහොත් මෙය ක්‍රියා නොකරනු ඇත. හිස සීරීමේ පන්ති විග්‍රහයක් ඇත.
ප්ලග් වොෂ්

0

මේක උත්සාහ කරන්න.

private int m = 0;
private int n = 0;
private Element<T>[][] elements = null;

public MatrixData(int m, int n)
{
    this.m = m;
    this.n = n;

    this.elements = new Element[m][n];
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            this.elements[i][j] = new Element<T>();
        }
    }
}

මට ඔබේ කේතය ක්‍රියාත්මක කළ නොහැක, ඔබේ Elementපන්තිය පැමිණෙන්නේ කොහෙන්ද?

0

මේ සඳහා පහසු, අවුල් සහගත ක්‍රියාමාර්ගයක් වනුයේ ඔබේ ප්‍රධාන පන්තියේ ඇතුළත දෙවන “දරන්නා” පන්තියක් කැදැල්ල කර ඔබේ දත්ත රඳවා ගැනීමට එය භාවිතා කිරීමයි.

public class Whatever<Thing>{
    private class Holder<OtherThing>{
        OtherThing thing;
    }
    public Holder<Thing>[] arrayOfHolders = new Holder<Thing>[10]
}

3
මෙය ඇත්ත වශයෙන්ම ක්‍රියාත්මක නොවේ. new Holder<Thing>[10]සාමාන්‍ය අරාව නිර්මාණයකි.
රේඩියෝඩෙෆ්

0

සමහර විට මෙම ප්‍රශ්නයට සම්බන්ධ නැති නමුත් මම generic array creationභාවිතා කිරීමේදී " " දෝෂය ලබා ගනිමින් සිටියදී

Tuple<Long,String>[] tupleArray = new Tuple<Long,String>[10];

මම පහත සඳහන් කෘති (සහ මා වෙනුවෙන් වැඩ කළෙමි) සමඟ @SuppressWarnings({"unchecked"}):

 Tuple<Long, String>[] tupleArray = new Tuple[10];

ඔව්, මෙය බෙහෙවින් සම්බන්ධ නැත, නමුත් මුල් බැස ඇත්තේ එකම කාරණා වලිනි (මකාදැමීම, අරාව සහසංයුජතාව). පරාමිතිගත
පෝල් බෙලෝරා

0

මෙම කේතය gen ලදායී ජනක අරාවක් නිර්මාණය කරයිදැයි මම කල්පනා කරමි.

public T [] createArray(int desiredSize){
    ArrayList<T> builder = new ArrayList<T>();
    for(int x=0;x<desiredSize;x++){
        builder.add(null);
    }
    return builder.toArray(zeroArray());
}

//zeroArray should, in theory, create a zero-sized array of T
//when it is not given any parameters.

private T [] zeroArray(T... i){
    return i;
}

සංස්කරණය කරන්න: සමහර විට එවැනි අරාවක් නිර්මාණය කිරීමේ විකල්ප ක්‍රමයක් නම්, ඔබට අවශ්‍ය ප්‍රමාණය දැනගෙන කුඩා නම්, අවශ්‍ය “ශුන්‍ය” ගණන ශුන්‍ය අරා විධානයට පෝෂණය කිරීම විය හැකිද?

පැහැදිලිවම මෙය createArray කේතය භාවිතා කිරීම තරම් බහුකාර්ය නොවේ.


නැත, මෙය ක්‍රියාත්මක නොවේ. මෙම varargs ක erasure නිර්මාණය Tවිට Tවර්ගයක් විචල්ය වන අතර, එනම් zeroArrayයම් නැවත Object[]. Http://ideone.com/T8xF91 බලන්න .
රේඩියෝඩෙෆ්

0

ඔබට කාස්ට් එකක් භාවිතා කළ හැකිය:

public class GenSet<Item> {
    private Item[] a;

    public GenSet(int s) {
        a = (Item[]) new Object[s];
    }
}

ඔබ මෙය යෝජනා කිරීමට යන්නේ නම්, ඔබ එහි සීමාවන් පැහැදිලි කළ යුතුය. aපංතියෙන් පිටත කිසි විටෙකත් නිරාවරණය නොකරන්න !
රේඩියෝඩෙෆ්

0

සාමාන්‍ය පෙළක් ආරම්භ කිරීමට ඇති නොහැකියාව මඟහරවා ගැනීම සඳහා මම සැබවින්ම සුවිශේෂී විසඳුමක් සොයා ගතිමි. ඔබ කළ යුත්තේ ටී වැනි සාමාන්‍ය විචල්‍යයට අනුව පන්තියක් නිර්මාණය කිරීමයි:

class GenericInvoker <T> {
    T variable;
    public GenericInvoker(T variable){
        this.variable = variable;
    }
}

ඉන්පසු ඔබේ අරාව පන්තියේදී එය එසේ ආරම්භ කරන්න:

GenericInvoker<T>[] array;
public MyArray(){
    array = new GenericInvoker[];
}

ආරම්භ කිරීම new Generic Invoker[]අනවසරයෙන් ගැටළුවක් ඇති කරයි නමුත් ඇත්ත වශයෙන්ම කිසිදු ගැටළුවක් නොවිය යුතුය.

අරාවෙන් ලබා ගැනීම සඳහා ඔබ අරාව [i] අමතන්න .එහි වෙනස් විය හැකිය:

public T get(int index){
    return array[index].variable;
}

අරාව ප්‍රතිප්‍රමාණනය කිරීම වැනි ඉතිරිය Arrays.copyOf () සමඟ කළ හැකිය:

public void resize(int newSize){
    array = Arrays.copyOf(array, newSize);
}

එකතු කිරීමේ ශ්‍රිතය මෙසේ එකතු කළ හැකිය:

public boolean add(T element){
    // the variable size below is equal to how many times the add function has been called 
    // and is used to keep track of where to put the next variable in the array
    arrays[size] = new GenericInvoker(element);
    size++;
}

1
ප්‍රශ්නය වූයේ සාමාන්‍ය පරාමිති වර්ගයේ පෙළක් නිර්මාණය කිරීම Tමිස කිසියම් පරාමිතිගත වර්ගයක පෙළක් නොවේ.
සොටීරියෝස් ඩෙලිමානොලිස්

එය එකම කාර්යය සම්පූර්ණ කරන අතර ඔබේ අභිරුචි එකතුව භාවිතා කිරීමට පහසු වන පරිදි පන්තියකට තල්ලු කිරීම අවශ්‍ය නොවේ.
කකුළුවන් නිහාරිකාව

කුමන කාර්යයද ? එය වචනාර්ථයෙන් වෙනස් කාර්යයකි: පරාමිතිගත වර්ගයක පෙළක් සහ සාමාන්‍ය වර්ගයේ පරාමිතියක පෙළක්.
Sotirios Delimanolis

සාමාන්‍ය වර්ගයකින් අරාවක් සෑදීමට එය ඔබට ඉඩ දෙයි? මුල්ම ගැටළුව වූයේ සාමාන්‍ය වර්ගයක් භාවිතා කර අරාව ආරම්භ කිරීමයි, එය මගේ ක්‍රමය භාවිතා කිරීමෙන් පරිශීලකයා පන්තියකට තල්ලු නොකර හෝ වස්තුවක් නූලකට දැමීමට උත්සාහ කිරීම වැනි පරීක්ෂා නොකළ දෝෂයක් ලබා දේ. මිරිස් මෙන්, මම කරන දෙයින් මම දක්ෂ නොවේ, මම ක්‍රමලේඛනය සඳහා පාසැලට ගොස් නැත, නමුත් මම සිතන්නේ අන්තර්ජාලයේ වෙනත් ළමයෙකු විසින් පවසනවාට වඩා කුඩා ආදානයක් ලැබිය යුතු බවයි.
කකුළුවන් නිහාරිකාව

මම සොටිරෝස් සමඟ එකඟ වෙමි. පිළිතුර ගැන සිතීමට ක්‍රම දෙකක් තිබේ. එක්කෝ එය වෙනත් ප්‍රශ්නයකට පිළිතුරක් හෝ ප්‍රශ්නය සාමාන්‍යකරණය කිරීමේ උත්සාහයකි. දෙකම වැරදියි / ප්‍රයෝජනවත් නොවේ. "සාමාන්‍ය අරාව" පන්තියක් ක්‍රියාත්මක කරන්නේ කෙසේද යන්න පිළිබඳ මග පෙන්වීමක් සොයන පුද්ගලයින් ප්‍රශ්න මාතෘකාව කියවන විට කියවීම නවත්වනු ඇත. ඔවුන් පිළිතුරු 30 ක් සහිත Q එකක් සොයාගත් විට, ඔවුන් අවසානය දක්වා අනුචලනය කිරීමට සහ SO නවකයෙකුගෙන් ශුන්‍ය ඡන්ද පිළිතුරක් කියවීමට බොහෝ දුරට ඉඩ නැත.
ස්ටීවන් සී

0

Vnportnoy ට අනුව වාක්‍ය ඛණ්ඩය

GenSet<Integer> intSet[] = new GenSet[3];

පුරවා ගැනීම සඳහා ශුන්‍ය යොමු දැක්වීම් සමූහයක් නිර්මාණය කරයි

for (int i = 0; i < 3; i++)
{
   intSet[i] = new GenSet<Integer>();
}

වර්ගය ආරක්ෂිතයි.


-1
private E a[];
private int size;

public GenSet(int elem)
{
    size = elem;
    a = (E[]) new E[size];
}

ඔබ සැමවිටම ඔබේ කේතයට පැහැදිලි කිරීමක් එක් කළ යුතු අතර, එය පළ කළ මුල් ප්‍රශ්නය විසඳීමට හේතුව පැහැදිලි කරන්න.
mjuarez

-1

සාමාන්‍ය අරා නිර්මාණය ජාවා හි තහනම් නමුත් ඔබට එය එසේ කළ හැකිය

class Stack<T> {
private final T[] array;
public Stack(int capacity) {
    array = (T[]) new Object[capacity];
 }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.