Integer.toString (int i) vs String.valueOf (int i)


176

ฉันสงสัยว่าทำไมวิธีการที่String.valueOf(int i)มีอยู่? ฉันใช้วิธีนี้ในการแปลงintเป็นStringและเพิ่งค้นพบInteger.toString(int i)วิธี

หลังจากดูการใช้งานวิธีการเหล่านี้ฉันเห็นว่าคนแรกเรียกคนที่สอง ดังนั้นการโทรทั้งหมดของฉันจะString.valueOf(int i)เกี่ยวข้องกับการโทรมากกว่าการโทรโดยตรงโดยตรงInteger.toString(int i)


3
เพียงเพื่อวัตถุประสงค์ในการอ้างอิง: stackoverflow.com/questions/3335685/integer-tostring
Bobby

คำตอบ:


46

เพียงสองวิธีที่ต่างกันในการทำสิ่งเดียวกัน อาจเป็นเหตุผลทางประวัติศาสตร์ (จำไม่ได้ว่ามีใครมาก่อน)


22
ใช่ แต่ถ้ามีอะไรที่ทำแบบเดียวกันไม่ได้หมายความว่าเป็นสิ่งเดียวกัน
Damian Leszczyński - Vash

3
String.valueOf (int) เพียงแค่เรียก Integer.toString (i) โดยตรง ดังนั้นวิธีที่ดีที่สุดในการเรียก Integer.toString (int)
djchapm

171

ในประเภท String เรามีวิธีการหลายค่าของ

static String   valueOf(boolean b) 
static String   valueOf(char c) 
static String   valueOf(char[] data) 
static String   valueOf(char[] data, int offset, int count) 
static String   valueOf(double d) 
static String   valueOf(float f) 
static String   valueOf(int i) 
static String   valueOf(long l) 
static String   valueOf(Object obj) 

อย่างที่เราเห็นวิธีการเหล่านั้นสามารถแก้ไขตัวเลขทุกชนิดได้

การใช้งานวิธีการเฉพาะทุกอย่างที่คุณนำเสนอ: ดังนั้นสำหรับจำนวนเต็มเรามี

Integer.toString(int i)

สำหรับคู่

Double.toString(double d)

และอื่น ๆ

ในความคิดของฉันนี่ไม่ใช่สิ่งประวัติศาสตร์ แต่มีประโยชน์สำหรับนักพัฒนาที่จะใช้วิธีการvalueOfจากคลาส String มากกว่าจากประเภทที่เหมาะสมเนื่องจากมันนำไปสู่การเปลี่ยนแปลงน้อยลงสำหรับเรา

ตัวอย่างที่ 1:

public String doStuff(int num) {

  // Do something with num...

  return String.valueOf(num);

 }

Sample2:

public String doStuff(int num) {

 // Do something with num...

 return Integer.toString(num);

 }

ดังที่เราเห็นในตัวอย่างที่ 2 เราต้องทำการเปลี่ยนแปลงสองอย่างในทางตรงกันข้ามกับตัวอย่างที่หนึ่ง

ในบทสรุปของฉันการใช้valueOfวิธีจากคลาส String นั้นมีความยืดหยุ่นมากกว่า


18
และอย่าลืมInteger.toString(int i, int radix)ว่าจะแปลงเป็นสายของฐานอื่นที่ไม่ใช่ 10
สตีเฟ่นพี

@Vash คุณช่วยอธิบายเกี่ยวกับการใช้สตริงว่างเพื่อแปลง int เป็น String เปรียบเทียบกับ String.valueOf ได้หรือไม่ เช่น) "" + int i = "i"? ไหนดีที่สุด
Kanagavelu Sugumar

1
ในการจัดรูปแบบ int เป็นสตริงคุณไม่ควรใช้ "" + i ไม่มีหัวใหญ่ แต่โดยทั่วไปเพราะไม่สง่า แทนที่จะใช้String.valueOf(int)คุณสามารถใช้String.format("%d",i);อ่านเพิ่มเติมได้ที่เว็บไซต์นี้docs.oracle.com/javase/6/docs/api/java/util/Formatter.html
Damian Leszczyński - Vash

ฉันหวังว่าออโต้บ็อกซ์นั้นฉลาดกว่าและเพิ่งเพิ่มการแปลงในการรวบรวมหรือบางอย่าง
Rob Grant

1
@RobertGrant การ autoboxing ไม่ใช่กรณีที่นี่ แต่เพื่อตอบข้อกังวลของคุณมันฉลาดเท่าที่คุณสามารถทำได้int i = new Integer("1");และในทางกลับกัน
Damian Leszczyński - Vash

52

สิ่งหนึ่งที่แตกต่างกันอย่างมากก็คือถ้าคุณเรียกใช้toString()วัตถุที่เป็นโมฆะคุณจะได้รับการใช้งานNullPointerExceptionในขณะที่String.valueOf()คุณไม่สามารถตรวจสอบค่าว่างได้


46
คำถามที่เป็นเรื่องเกี่ยวกับInteger.toString(int i)การstaticวิธีการ ไม่มีnullวัตถุที่เป็นไปได้
Petr Janeček

14
Integer i = null; i.toString(); // Null pointer exception!! String.valueOf(i); // No exception
manish_s

10
@Manis Kumar: ตัวอย่างของคุณจะไม่ใช้String.valueOf(int i)วิธีการString.valueOf(Object obj)นี้ ทั้งนี้คำถามที่เป็นเรื่องเกี่ยวกับดั้งเดิมค่านิยมที่มีความเป็นไปได้ของไม่มีint null
hleinone

1
@manish_s มันค่อนข้างชัดเจนจากตัวอย่างที่ไม่มีใครพูดถึง Object type Integer เรากำลังพูดถึงดั้งเดิมเท่านั้น
Daniel Ochoa

2
@manish_s: สหกรณ์ไม่ได้พูดแต่Integer.toString() Integer.toString(int i)นั่นเป็นวิธีการคงที่ ( docs.oracle.com/javase/7/docs/api/java/lang/… )
LarsH

13

คลาส String ให้วิธีการ valueOf สำหรับประเภทดั้งเดิมและประเภทวัตถุดังนั้นฉันคิดว่ามันเป็นวิธีการอำนวยความสะดวกที่ทุกคนสามารถเข้าถึงได้ผ่านชั้นเดียว

NB ผลการจัดทำโปรไฟล์

Average intToString = 5368ms, ค่าเฉลี่ยสตริง = 5689ms (สำหรับการดำเนินการ 100,000,000 ครั้ง)

public class StringIntTest {


    public static long intToString () {
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 100000000; i++) {
            String j = Integer.toString(i);
        }
        long finishTime = System.currentTimeMillis();

        return finishTime - startTime;
    }

    public static long stringValueOf () {

        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 100000000; i++) {
            String j = String.valueOf(i);
        }
        long finishTime = System.currentTimeMillis();

        return finishTime - startTime;
    }

    public static void main(String[] args) {
        long intToStringElapsed = 0;
        long stringValueOfElapsed = 0;
        for (int i = 0; i < 10; i++) {
            intToStringElapsed += intToString();
            stringValueOfElapsed+= stringValueOf();
        }
        System.out.println("Average intToString = "+ (intToStringElapsed /10));
        System.out.println("Average stringValueOf = " +(stringValueOfElapsed / 10));
    }
}

7
การรวบรวมสถานะของคุณควรมีช่วงเวลา "อุ่นเครื่อง" ไม่เช่นนั้น JIT จะทำการบิดเบือนสิ่งต่างๆ ที่กล่าวมานั้นความแตกต่าง 300ms ในการดำเนินงาน 10 ^ 8 นั้นเล็กมากจนไม่มีความสำคัญเลย
Cameron Skinner

1
@Kingo ฉันไม่คิดว่ากรณีทดสอบของคุณถูกต้อง เพราะคุณกำลังกำหนดค่าให้String jแต่ไม่เคยใช้ คอมไพเลอร์พื้นฐานอาจปรับปรุงสิ่งนี้ มันจะดีกว่าที่จะผ่านวัตถุ j ในวิธีการที่แตกต่างกันและดำเนินการหลอกตา
Rakesh

1
คุณไม่ควรเขียนมาตรฐานขนาดเล็กที่ปลูกในบ้านด้วยวิธีนี้ ถ้าคุณใช้JMH มันจะดูแล warmup การวัดเวลาพยายามอิสระหลายครั้ง (forks Java!) และทำให้โค้ดมีขนาดเล็กดูเหมือน (รวมผลลัพธ์สำหรับวิธีการและค่าต่าง ๆ - รันไทม์ 7 นาที): gist.github.com/ecki/ 399136f4fd59c1d110c1 (สปอยเลอร์: "" + n วอน)
eckes

5
ขอบคุณเพื่อน แต่คำตอบของฉันเมื่อ 5 ปีที่แล้ว! JMH เปิดตัวเฉพาะในปี 2556: P
Kingo

9

จากแหล่ง Java:

/**
 * Returns the string representation of the {@code int} argument.
 * <p>
 * The representation is exactly the one returned by the
 * {@code Integer.toString} method of one argument.
 *
 * @param   i   an {@code int}.
 * @return  a string representation of the {@code int} argument.
 * @see     java.lang.Integer#toString(int, int)
 */
public static String valueOf(int i) {
    return Integer.toString(i);
}

ดังนั้นพวกเขาจึงให้ผลลัพธ์ที่เหมือนกันและหนึ่งในความเป็นจริงการโทรอื่น ๆ String.valueOf มีความยืดหยุ่นมากขึ้นถ้าคุณอาจเปลี่ยนชนิดในภายหลัง


8

ถ้าคุณดูที่รหัสแหล่งสำหรับStringชั้นก็จริงเรียกเมื่อคุณเรียกInteger.toString()valueOf()

ที่ถูกกล่าวว่าInteger.toString()อาจจะเร็วกว่าเล็กน้อยหากวิธีการโทรไม่ได้รับการปรับให้เหมาะสมในเวลารวบรวม (ซึ่งอาจเป็น)


ใช่และ "" + n เร็วยิ่งขึ้น ดูgist.github.com/ecki/399136f4fd59c1d110c1
eckes

3

การดำเนินการตามString.valueOf()ที่คุณเห็นเป็นวิธีที่ง่ายที่สุดในการทำตามสัญญาที่ระบุใน API: "การแสดงนั้นเป็นสิ่งที่ส่งคืนโดยInteger.toString()วิธีการของอาร์กิวเมนต์หนึ่งข้อ"


2

เพื่อตอบคำถาม OPs มันเป็นเพียงตัวช่วยห่อหุ้มเพื่อให้มีการโทรอีกสายหนึ่งและเลือกสไตล์ได้และนั่นก็คือ ฉันคิดว่ามีข้อมูลที่ผิดมากมายที่นี่และสิ่งที่ดีที่สุดที่นักพัฒนา Java สามารถทำได้คือดูที่การนำไปใช้สำหรับแต่ละวิธีมันคือคลิกหนึ่งหรือสองครั้งใน IDE ใด ๆ คุณจะเห็นได้อย่างชัดเจนว่าString.valueOf(int)เป็นเพียงการเรียกร้องInteger.toString(int)ให้คุณ

ดังนั้นจึงมีความแตกต่างเป็นศูนย์อย่างแน่นอนในการที่พวกเขาทั้งสองสร้างบัฟเฟอร์ถ่านเดินผ่านตัวเลขในจำนวนนั้นคัดลอกที่เป็นสตริงใหม่และส่งกลับ (ดังนั้นแต่ละคนกำลังสร้างวัตถุ String หนึ่ง) ข้อแตกต่างเพียงอย่างเดียวคือการโทรเพิ่มเติมหนึ่งครั้ง

ดังนั้นมันจึงไม่ใช่สิ่งที่คุณโทรหานอกจากความสอดคล้องกับรหัส ในฐานะที่เป็นความคิดเห็นเกี่ยวกับโมฆะก็ต้องใช้ดั้งเดิมดังนั้นจึงไม่สามารถเป็นโมฆะ! คุณจะได้รับข้อผิดพลาดในการคอมไพล์เวลาหากคุณไม่เริ่มต้น int ที่ถูกส่งผ่าน ดังนั้นจึงไม่มีความแตกต่างในวิธีการจัดการ nulls เนื่องจากไม่มีอยู่ในกรณีนี้


คุณช่วยแยกข้อความของคุณออกเป็นบางส่วนได้ไหม อ่านยากมาก
Magnilex

มีสิ่งที่เข้าใจผิดมากมายใน OP นี้ โพสต์ของคุณคือคำตอบที่ดีที่สุดสำหรับฉัน! ขอบคุณ
aksappy

1

คุณไม่ควรกังวลเกี่ยวกับการโทรเพิ่มนี้ที่ทำให้คุณมีปัญหาเรื่องประสิทธิภาพ หากมีค่าใช้จ่ายใด ๆ มันจะน้อยมากและควรมีความสำคัญในภาพรวมของสิ่งต่าง ๆ

อาจเป็นเหตุผลว่าทำไมทั้งสองมีอยู่เพื่อให้สามารถอ่านได้ ในบริบทของการแปลงเป็นหลายประเภทการStringโทรที่หลากหลายไปยังString.valueOf(SomeType)อาจอ่านได้ง่ายกว่าการSomeType.toStringโทรที่หลากหลาย


1
ที่จริงแล้วการโทรหนึ่งบรรทัดดังกล่าวจะได้รับการ inline ค่อนข้างเร็ว
Tassos Bassoukos

แม้จะอยู่ในวงเรียกเวลา 1 000 000 String.valueof () ??
Manuel Selva

@Manuel: คุณโปรไฟล์หรือไม่ คุณพบว่าในที่นี้เป็นปัญหาประสิทธิภาพการทำงานของคุณหรือไม่ คุณแน่ใจหรือไม่ว่าคุณไม่ได้เพิ่มประสิทธิภาพก่อนเวลาอันควร @TTOSOS: ใช่ว่ามีโอกาสมากเช่นกัน แต่ไม่ว่าด้วยวิธีใดฉันจะไม่ต้องกังวลเกี่ยวกับเรื่องนี้จนกว่าโปรไฟล์จะบอกว่ามีปัญหากับการโทรนี้โดยเฉพาะ
polygenelubricants

อันที่จริงมานูเอลฉันคาดว่าจะวนซ้ำ 1000000 ครั้งเพื่อให้อินไลน์บ่อยกว่าการไปหนึ่งหรือสองครั้ง ถึงกระนั้นมันก็เป็นส่วนเล็ก ๆ ของเวลาไม่ว่ามันจะวนกี่ครั้งก็ตาม
corsiKa

ไม่ แต่ฉันแน่ใจว่าไม่มีคอขวดในแอปของฉัน ฉันแค่ถามคำถามนี้เพราะฉันไม่เห็นข้อกังวลเกี่ยวกับการอ่านที่นี่และดังนั้นฉันคิดว่าฉันต้องใช้รหัสที่เหมาะสมยิ่งขึ้นแม้ว่ากำไรจะเป็น 0 คุณไม่เห็นด้วยใช่ไหม
Manuel Selva

1

openion ของฉันคือ valueof () มักจะเรียกว่า tostring () สำหรับ Representaion และดังนั้นสำหรับ rpresentaion ของประเภท primtive valueof คือ generalized.and java โดยค่าเริ่มต้นไม่สนับสนุนประเภทข้อมูล object .here Integer.toString (int i) สร้างขีด จำกัด การแปลงสำหรับจำนวนเต็มเท่านั้น


1

ไม่มีความแตกต่างระหว่าง Integer.toString (5) และ String.valueOf (5);

เนื่องจาก String.valueOf ส่งคืน:

public static String valueOf(int i) {
    return Integer.toString(i);
}
public static String valueOf(float f) {
    return Float.toString(f);
}

ฯลฯ ..


0

การใช้เมธอด String.valueOf () คุณไม่ต้องกังวลเกี่ยวกับข้อมูล (ไม่ว่าจะเป็น int, long, char, char [], บูลีน, Object) คุณสามารถโทร:

  • String คงที่ valueOf ()

การใช้ไวยากรณ์ String.valueOf () เพียงอย่างเดียวสามารถทำสิ่งที่คุณผ่านเป็นพารามิเตอร์ที่ถูกแปลงเป็นสตริงและส่งกลับ ..

มิฉะนั้นถ้าคุณใช้ Integer.toString (), Float.toString () เป็นต้น (เช่น SomeType.toString ()) คุณจะต้องตรวจสอบประเภทข้อมูลของพารามิเตอร์ที่คุณต้องการแปลงเป็นสตริง ดังนั้นมันจะดีกว่าที่จะใช้ String.valueOf () สำหรับการแปลงดังกล่าว

หากคุณมีอาเรย์ของคลาสอ็อบเจ็กต์ที่มีค่าต่างกันเช่น Integer, Char, Float เป็นต้นโดยใช้เมธอด String.valueOf () คุณสามารถแปลงองค์ประกอบของอาเรย์เป็นรูปแบบสตริงได้อย่างง่ายดาย ในทางตรงกันข้ามถ้าคุณต้องการใช้ SomeType.toString () ในตอนแรกคุณจะต้องรู้ว่ามีคลาสประเภทข้อมูลของพวกเขา (อาจใช้โอเปอเรเตอร์ "instanceOf") จากนั้นคุณเท่านั้นที่จะสามารถดำเนินการพิมพ์ได้

String.valueOf () วิธีการเมื่อเรียกตรงกับพารามิเตอร์ที่ผ่าน (ไม่ว่าจะเป็นจำนวนเต็ม, Char, ลอย ฯลฯ ) และโดยใช้วิธีการมากไปเรียกว่า "valueOf ()" วิธีการที่พารามิเตอร์ได้รับการจับคู่แล้วภายในวิธีการของพวกเขา การโทรโดยตรงไปยังวิธีการ "toString ()" ที่สอดคล้องกัน ..

ดังนั้นเราสามารถดูว่าค่าใช้จ่ายในการตรวจสอบประเภทข้อมูลแล้วเรียกวิธีการ "toString ()" ที่สอดคล้องกันจะถูกลบออกเท่านั้นเราต้องการที่จะเรียกวิธีการ String.valueOf () ไม่สนใจว่าสิ่งที่เราต้องการแปลงเป็นสตริง

สรุป: วิธีการ String.valueOf () มีความสำคัญเพียงค่าใช้จ่ายของการโทรอีกหนึ่ง


-3

toString ()

  1. มีอยู่ในคลาส Object โดยทั่วไปจะแทนที่ในคลาสที่ได้รับ
  2. จำเป็นต้องเรียกใช้เมธอด toString ()

มูลค่าของ()

  1. วิธีคงที่โอเวอร์โหลดที่มีอยู่ในคลาส String
  2. จัดการประเภทดั้งเดิมเช่นเดียวกับประเภทวัตถุ

    Integer a = null;
    System.out.println(Integer.toString()) ; NUll pointer exception
    System.out.println(String.valueOf() ; give NULL as value

ตรวจสอบลิงค์นี้มันดีมาก http://code4reference.com/2013/06/which-one-is-better-valueof-or-tostring/

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.