Integer i = 128;
Integer b = 128;
Boolean b2= (i==b);
چرامقدار b2 در کد بالا false میباشد؟
همانند مکانیزم String pool. جاوا برای اعداد نیز مکانیزمی به نام Integer pool دارد و اعداد در بازه ی -۱۲۸ تا ۱۲۷ را کش میکند و اگر دوتا Integer به یکی از مقادیر در این بازه اشاره کنند درواقع هردو به یک خانه در حافظه اشاره میکنند .
به این دلیل خانه های حافظه ی آنها یکسان است
اما اگر به مقداری خارج از محدوده ی بالا اشاره کنند .. دیگر خانه های آنها یکسان نخواهد بود درنتیجه b2==false خواهد بود.
پس :
Integer i = 127;
Integer b = 127;
Boolean b2= (i==b);
در کد فوق b2 ترو خواهد بود
توجه کنید که اگر داشته باشیم :
Integer i = new Integer(128);
Integer b = 128;
Boolean b2= (i==b);
بی۲ فالس خواهد بود زیرا با new کردن ما مکانیزم کش را نادیده میگیریم.
این نکته قابل ذکر است که در primitive type ها این داستان های کشینگ را نداریم و در برابری بین دو int صرفا مقدار آن دو مقایسه میشود پس :
Integer i = 128;
Integer b = 128;
Boolean b2= (i==b.intValue());
در کد فوق b2 نیز true خواهد بود (با اینکه i و b به یک مکان در حافظه اشاره نمیکنند اما چون آنباکس میشوند صرفا مقدار آنها چک میشود)
@this_java
Integer b = 128;
Boolean b2= (i==b);
چرامقدار b2 در کد بالا false میباشد؟
همانند مکانیزم String pool. جاوا برای اعداد نیز مکانیزمی به نام Integer pool دارد و اعداد در بازه ی -۱۲۸ تا ۱۲۷ را کش میکند و اگر دوتا Integer به یکی از مقادیر در این بازه اشاره کنند درواقع هردو به یک خانه در حافظه اشاره میکنند .
به این دلیل خانه های حافظه ی آنها یکسان است
اما اگر به مقداری خارج از محدوده ی بالا اشاره کنند .. دیگر خانه های آنها یکسان نخواهد بود درنتیجه b2==false خواهد بود.
پس :
Integer i = 127;
Integer b = 127;
Boolean b2= (i==b);
در کد فوق b2 ترو خواهد بود
توجه کنید که اگر داشته باشیم :
Integer i = new Integer(128);
Integer b = 128;
Boolean b2= (i==b);
بی۲ فالس خواهد بود زیرا با new کردن ما مکانیزم کش را نادیده میگیریم.
این نکته قابل ذکر است که در primitive type ها این داستان های کشینگ را نداریم و در برابری بین دو int صرفا مقدار آن دو مقایسه میشود پس :
Integer i = 128;
Integer b = 128;
Boolean b2= (i==b.intValue());
در کد فوق b2 نیز true خواهد بود (با اینکه i و b به یک مکان در حافظه اشاره نمیکنند اما چون آنباکس میشوند صرفا مقدار آنها چک میشود)
@this_java
👍8
codeconventions-150003.pdf
128.9 KB
Don’t make any instance or class variable public without good reason. Often, instance
variables don’t need to be explicitly set or gotten—often that happens as a side effect of
method calls.
-Java code conventions
variables don’t need to be explicitly set or gotten—often that happens as a side effect of
method calls.
-Java code conventions
👍3
مقایسه ی Type wrapper ها و primitive type ها از نظر Performance
public static void main(String[] args) {
int repeats = 40000000;
long time;
time = System.currentTimeMillis();
long counterA = 0L;
for (int i = 0; i < repeats; i++) {
counterA = counterA + 4L;
}
System.out.println(counterA + " A: " + (System.currentTimeMillis() - time) + " ms");
time = System.currentTimeMillis();
Long counterB = 0L;
for (int i = 0; i < repeats; i++) {
counterB = counterB + 4L;
}
System.out.println(counterB + " B: " + (System.currentTimeMillis() - time) + " ms");
}
خروجی :
160000000 A: 0 ms
160000000 B: 284 ms
نتایج ممکن است با توجه به پردازنده, نسخه ی جاوا و... شما متفاوت باشد
دلیل نتایج فوق واضح است :
Type wrapper ها باید در heap
ذخیره شوند
و ساخت اشیا در heap هزینه ی بیشتری نسبت به stack دارد
بیاید کد بالا را بار دیگر , و اینبار به جای استفاده از autoboxing , از valueOf استفاده کنیم:
public static void main(String[] args) {
int repeats = 40000000;
long time;
time = System.currentTimeMillis();
long counterA = 0L;
for (int i = 0; i < repeats; i++) {
counterA = counterA + 4L;
}
System.out.println(counterA + " A: " + (System.currentTimeMillis() - time) + " ms");
time = System.currentTimeMillis();
Long counterB = Long.valueOf(0L);
for (int i = 0; i < repeats; i++) {
counterB = counterB + 4L;
}
System.out.println(counterB + " B: " + (System.currentTimeMillis() - time) + " ms");
}
خروجی :
160000000 A: 0 ms
160000000 B: 237 ms
دلیل این امر چیست؟
تعریف type wrapper به صورت بالا از نظر بایت کد تفاوت چندانی با تعریف به صورت زیر ندارد:
Long l = new Long(0L);
این کد همیشه یک شی جدید از Long با مقدار 0 ایجاد میکند . اما جاوا بصورت پیشفرض تعدادی از مقادیر پر استفاده را از اول اجرای برنامه ذخیره میکند تا تفاوت سرعت فاحشی میان primitive type و type wrapper بوجود نیاید :
@IntrinsicCandidate
public static Long valueOf(long l) {
final int offset = 128;
if (l >= -128 && l <= 127) { // will cache
return LongCache.cache[(int)l + offset];
}
return new Long(l);
}
با مشاهده ی متد valueOf (این متد را تحت عنوان static factory method میشناسیم)میتوان دید مقادیر -128 تا 127 کش شده اند .
و خارج از این محدوده , تفاوتی میان
Long l = 128L;
و
Long l = Long.valueOf(128L);
وجود ندارد.(البته لازم به ذکر است احتمالا اگر در برنامه ی شما یک عدد زیاد استفاده شود ان عدد نیز کش میشود)
البته استفاده از سازنده ی Long از نسخه ی 9 به بعد منسوخ شده و توسط جاوا پیشنهاد شده صرفا متد valueOf برای استفاده از Type wrapper ها به کار برده شود.
public static void main(String[] args) {
int repeats = 40000000;
long time;
time = System.currentTimeMillis();
long counterA = 0L;
for (int i = 0; i < repeats; i++) {
counterA = counterA + 4L;
}
System.out.println(counterA + " A: " + (System.currentTimeMillis() - time) + " ms");
time = System.currentTimeMillis();
Long counterB = 0L;
for (int i = 0; i < repeats; i++) {
counterB = counterB + 4L;
}
System.out.println(counterB + " B: " + (System.currentTimeMillis() - time) + " ms");
}
خروجی :
160000000 A: 0 ms
160000000 B: 284 ms
نتایج ممکن است با توجه به پردازنده, نسخه ی جاوا و... شما متفاوت باشد
دلیل نتایج فوق واضح است :
Type wrapper ها باید در heap
ذخیره شوند
و ساخت اشیا در heap هزینه ی بیشتری نسبت به stack دارد
بیاید کد بالا را بار دیگر , و اینبار به جای استفاده از autoboxing , از valueOf استفاده کنیم:
public static void main(String[] args) {
int repeats = 40000000;
long time;
time = System.currentTimeMillis();
long counterA = 0L;
for (int i = 0; i < repeats; i++) {
counterA = counterA + 4L;
}
System.out.println(counterA + " A: " + (System.currentTimeMillis() - time) + " ms");
time = System.currentTimeMillis();
Long counterB = Long.valueOf(0L);
for (int i = 0; i < repeats; i++) {
counterB = counterB + 4L;
}
System.out.println(counterB + " B: " + (System.currentTimeMillis() - time) + " ms");
}
خروجی :
160000000 A: 0 ms
160000000 B: 237 ms
دلیل این امر چیست؟
تعریف type wrapper به صورت بالا از نظر بایت کد تفاوت چندانی با تعریف به صورت زیر ندارد:
Long l = new Long(0L);
این کد همیشه یک شی جدید از Long با مقدار 0 ایجاد میکند . اما جاوا بصورت پیشفرض تعدادی از مقادیر پر استفاده را از اول اجرای برنامه ذخیره میکند تا تفاوت سرعت فاحشی میان primitive type و type wrapper بوجود نیاید :
@IntrinsicCandidate
public static Long valueOf(long l) {
final int offset = 128;
if (l >= -128 && l <= 127) { // will cache
return LongCache.cache[(int)l + offset];
}
return new Long(l);
}
با مشاهده ی متد valueOf (این متد را تحت عنوان static factory method میشناسیم)میتوان دید مقادیر -128 تا 127 کش شده اند .
و خارج از این محدوده , تفاوتی میان
Long l = 128L;
و
Long l = Long.valueOf(128L);
وجود ندارد.(البته لازم به ذکر است احتمالا اگر در برنامه ی شما یک عدد زیاد استفاده شود ان عدد نیز کش میشود)
البته استفاده از سازنده ی Long از نسخه ی 9 به بعد منسوخ شده و توسط جاوا پیشنهاد شده صرفا متد valueOf برای استفاده از Type wrapper ها به کار برده شود.
Oracle
Autoboxing and Unboxing (The Java™ Tutorials >
Learning the Java Language > Numbers and Strings)
Learning the Java Language > Numbers and Strings)
This beginner Java tutorial describes fundamentals of programming in the Java programming language
👍10
public static int fastExp(int base,int exponential){
if(exponential==0){
return 1;
} else if(exponential==1){
return base;
}
int R = fastExp(base,exponential/2);
if(exponential%2==0){
return R*R;
}
return R*base*R;
}
الگوریتم fast exponential
پیچیدگی زمانی:
O(lgn)
پیچیدگی زمانی الگوریتم معمولی :
O(n)
دسته بندی : Divide and conquer
@this_java
if(exponential==0){
return 1;
} else if(exponential==1){
return base;
}
int R = fastExp(base,exponential/2);
if(exponential%2==0){
return R*R;
}
return R*base*R;
}
الگوریتم fast exponential
پیچیدگی زمانی:
O(lgn)
پیچیدگی زمانی الگوریتم معمولی :
O(n)
دسته بندی : Divide and conquer
@this_java
👍4
Permutations of given array:
Subsets of given array:
public class Runner {
public static void main(String[] args) {
int a[]={1,2,3};
permutation(a,0);
}
private static void permutation(int[] a,int k) {
if(k==a.length-1){
System.out.println(Arrays.toString(a));
return;
}
for (int i = k; i <a.length; i++) {
int temp=a[k];
a[k]=a[i];
a[i]=temp;
permutation(a,k+1);
temp=a[k];
a[k]=a[i];
a[i]=temp;
}
}
}Subsets of given array:
public static void printSubSets(int arr[],int last,int k[]){
if(last==arr.length){
System.out.println(Arrays.toString(k));
return;
}int x = arr[last];
k[last] = x;
printSubSets(arr, last + 1, k);
k[last] = -1;
printSubSets(arr, last + 1, k);
}
public static void main(String[] args) {
int arr[]={1,2,3};
int k[]={-1,-1,-1};
printSubSets(arr,0,k);
}
Forwarded from Learn Java
problem is to find a path from the upper-left corner to the lower-right corner
of an n × n grid, with the restriction that we may only move down and right. Each
square contains an integer, and the path should be constructed so that the sum of the
values along the path is as large as possible.
divide and conquer approach:
of an n × n grid, with the restriction that we may only move down and right. Each
square contains an integer, and the path should be constructed so that the sum of the
values along the path is as large as possible.
divide and conquer approach:
public static int maxPath(int value[][],int x,int y){dynamic programming approach:
if(x==0 || y==0){
return value[x][y];
}
int max= Integer.MIN_VALUE;
max = Math.max(maxPath(value,x-1,y),maxPath(value,x,y-1))+value[x][y];
return max;
}
public static int maxPath(int value[][],int x,int y,int memory[][]){Driver code:
if(x==0 || y==0){
return value[x][y];
}
if(memory[x][y]!=Integer.MIN_VALUE){
return memory[x][y];
}
int max= Integer.MIN_VALUE;
max = Math.max(maxPath(value,x-1,y),maxPath(value,x,y-1))+value[x][y];
memory[x][y]=max;
return max;
}
public static void main(String[] args) {
int value[][]= {
{3,7,9,2,7},
{9,8,3,5,5},
{1,7,9,8,5},
{3,8,6,4,10},
{6,3,9,7,8}
};
int mem[][]= new int[5][5];
for(int i=0;i<mem.length;i++) {
Arrays.fill(mem[i],Integer.MIN_VALUE);
}
System.out.println(maxPath(value,4,4,mem));
}
👍6