سؤال

لدي قائمة من الأعداد الصحيحة، List<Integer> وأرغب في تحويل كافة الكائنات الصحيحة إلى سلاسل، وبالتالي الانتهاء من جديد List<String>.

بطبيعة الحال، يمكنني إنشاء جديد List<String> وحلقة من خلال قائمة الاتصال String.valueOf() لكل عدد صحيح، ولكن كنت أتساءل عما إذا كان هناك أفضل (اقرأ: أكثر تلقائية) طريقة القيام بذلك؟

هل كانت مفيدة؟

المحلول

بقدر ما أعرف، التكرار وإنشاء مثيل هو الطريقة الوحيدة للقيام بذلك.شيء من هذا القبيل (للمساعدة المحتملة للآخرين، لأنني متأكد من أنك تعرف كيفية القيام بذلك):

List<Integer> oldList = ...
/* Specify the size of the list up front to prevent resizing. */
List<String> newList = new ArrayList<String>(oldList.size()) 
for (Integer myInt : oldList) { 
  newList.add(String.valueOf(myInt)); 
}

نصائح أخرى

استخدام مجموعات جوجل من مشروع الجوافة, ، يمكنك استخدام transform الطريقة في القوائم فصل

import com.google.common.collect.Lists;
import com.google.common.base.Functions

List<Integer> integers = Arrays.asList(1, 2, 3, 4);

List<String> strings = Lists.transform(integers, Functions.toStringFunction());

ال List عاد بواسطة transform هو منظر في القائمة الخلفية - سيتم تطبيق التحويل على كل وصول إلى القائمة المحولة.

انتبه أن Functions.toStringFunction() سوف يرمي أ NullPointerException عند تطبيقه على القيمة null، استخدمه فقط إذا كنت متأكدًا من أن قائمتك لن تحتوي على قيمة null.

الحل لجافا 8.أطول قليلًا من إصدار Guava، لكن على الأقل لا يتعين عليك تثبيت مكتبة.

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

//...

List<Integer> integers = Arrays.asList(1, 2, 3, 4);
List<String> strings = integers.stream().map(Object::toString)
                                        .collect(Collectors.toList());

ما تفعله جيد، ولكن إذا شعرت بالحاجة إلى "Java-it-up"، فيمكنك استخدام ملف محول و ال طريقة جمع من أباتشي كومنز, ، على سبيل المثال:

public class IntegerToStringTransformer implements Transformer<Integer, String> {
   public String transform(final Integer i) {
      return (i == null ? null : i.toString());
   }
}

..وثم..

CollectionUtils.collect(
   collectionOfIntegers, 
   new IntegerToStringTransformer(), 
   newCollectionOfStrings);

يُظهر مصدر String.valueOf هذا:

public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

ليس هذا مهمًا كثيرًا، لكنني سأستخدم toString.

بدلاً من استخدام String.valueOf سأستخدم .toString();إنه يتجنب بعض الملاكمة الآلية التي وصفها @ johnathan.holland

يقول javadoc أن القيمة تُرجع نفس الشيء الذي يُرجعه Integer.toString().

List<Integer> oldList = ...
List<String> newList = new ArrayList<String>(oldList.size());

for (Integer myInt : oldList) { 
  newList.add(myInt.toString()); 
}

إليك حلًا أحادي الخط بدون غش مع مكتبة غير تابعة لـ JDK.

List<String> strings = Arrays.asList(list.toString().replaceAll("\\[(.*)\\]", "$1").split(", "));

حل آخر باستخدام الجوافة وجافا 8

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<String> strings = Lists.transform(numbers, number -> String.valueOf(number));

ليست Java أساسية، وليست عامة، ولكن مكتبة مجموعات جاكرتا العامة الشهيرة تحتوي على بعض التجريدات المفيدة لهذا النوع من المهام.على وجه التحديد، قم بإلقاء نظرة على طرق التجميع الموجودة

CollectionUtils

شيء يجب مراعاته إذا كنت تستخدم بالفعل مجموعات المشاعات في مشروعك.

إلى الأشخاص المهتمين بـ "الملاكمة" في إجابة jsight:لا يوجد. String.valueOf(Object) يستخدم هنا، ولا يوجد فتح لعلبة int يتم تنفيذها من أي وقت مضى.

سواء كنت تستخدم Integer.toString() أو String.valueOf(Object) يعتمد على الطريقة التي تريد بها التعامل مع القيم الخالية المحتملة.هل تريد طرح استثناء (ربما)، أو لديك سلاسل "فارغة" في قائمتك (ربما).إذا كان الأول، هل تريد رمي NullPointerException أو نوع آخر؟

هناك أيضًا عيب صغير في استجابة jsight: List هي واجهة، ولا يمكنك استخدام عامل التشغيل الجديد عليها.ربما سأستخدم أ java.util.ArrayList في هذه الحالة، خاصة وأننا نعرف مقدمًا المدة التي من المحتمل أن تستغرقها القائمة.

@ جوناثان:قد أكون مخطئًا، لكنني أعتقد أن String.valueOf() في هذه الحالة ستستدعي الدالة String.valueOf(Object) بدلاً من وضعها في مربع String.valueOf(int).تقوم String.valueOf(Object) بإرجاع "فارغة" فقط إذا كانت فارغة أو تستدعي Object.toString() إذا كانت غير فارغة، وهو ما لا ينبغي أن يتضمن الملاكمة (على الرغم من أنه من الواضح أن إنشاء كائنات سلسلة جديدة متضمن).

أعتقد أن استخدام Object.toString() لأي غرض آخر غير تصحيح الأخطاء ربما يكون فكرة سيئة حقًا، على الرغم من أن الاثنين في هذه الحالة متكافئان وظيفيًا (بافتراض عدم احتواء القائمة على قيم خالية).للمطورين الحرية في تغيير سلوك أي أسلوب toString() دون أي تحذير، بما في ذلك أساليب toString() لأي فئة في المكتبة القياسية.

لا تقلق حتى بشأن مشاكل الأداء الناجمة عن عملية الملاكمة/فتح الصندوق.إذا كان الأداء أمرًا بالغ الأهمية، فما عليك سوى استخدام المصفوفة.إذا كان الأمر بالغ الأهمية حقًا، فلا تستخدم Java.إن محاولة التفوق على JVM لن تؤدي إلا إلى وجع القلب.

الجواب للخبراء فقط:

    List<Integer> ints = ...;
    String all = new ArrayList<Integer>(ints).toString();
    String[] split = all.substring(1, all.length()-1).split(", ");
    List<String> strs = Arrays.asList(split);

لامبدج يسمح للقيام بذلك بطريقة بسيطة جدا وقابلة للقراءة.على سبيل المثال، لنفترض أن لديك قائمة من الأعداد الصحيحة وتريد تحويلها في تمثيل السلسلة المقابل، يمكنك كتابة شيء من هذا القبيل؛

List<Integer> ints = asList(1, 2, 3, 4);
Iterator<String> stringIterator = convertIterator(ints, new Converter<Integer, String> {
    public String convert(Integer i) { return Integer.toString(i); }
}

يطبق Lambdaj وظيفة التحويل فقط أثناء تكرار النتيجة.

لا يمكنك تجنب "أعباء الملاكمة"؛يمكن لحاويات Java العامة المزيفة تخزين الكائنات فقط، لذلك يجب وضع ints الخاص بك في أعداد صحيحة.من حيث المبدأ، يمكن تجنب التحويل من Object إلى Integer (نظرًا لأنه لا معنى له، لأن Object جيد بما يكفي لكل من String.valueOf وObject.toString) لكنني لا أعرف ما إذا كان المترجم ذكيًا بما يكفي للقيام بذلك.يجب أن يكون التحويل من String إلى Object أمرًا محظورًا إلى حدٍ ما، لذلك لن أميل إلى القلق بشأن ذلك.

للمتعة فقط، الحل باستخدام إطار عمل jsr166y fork-join الذي ينبغي أن يكون في JDK7.

import java.util.concurrent.forkjoin.*;

private final ForkJoinExecutor executor = new ForkJoinPool();
...
List<Integer> ints = ...;
List<String> strs =
    ParallelArray.create(ints.size(), Integer.class, executor)
    .withMapping(new Ops.Op<Integer,String>() { public String op(Integer i) {
        return String.valueOf(i);
    }})
    .all()
    .asList();

(تنصل:لم يتم تجميعها.لم يتم الانتهاء من المواصفات.إلخ.)

من غير المحتمل أن يكون JDK7 يحتوي على القليل من الاستدلال النوعي والسكر النحوي لجعل ذلك باستخدام Mapping أقل تفصيلاً:

    .withMapping(#(Integer i) String.valueOf(i))

هذا هو الشيء الأساسي الذي يجب القيام به ولن أستخدم مكتبة خارجية (سيؤدي ذلك إلى تبعية في مشروعك ربما لا تحتاج إليها).

لدينا فئة من الأساليب الثابتة المصممة خصيصًا للقيام بهذا النوع من الوظائف.نظرًا لأن الكود الخاص بذلك بسيط جدًا، فقد سمحنا لـ Hotspot بإجراء التحسين نيابةً عنا.يبدو أن هذا موضوع في الكود الخاص بي مؤخرًا:اكتب رمزًا بسيطًا جدًا (مباشرًا) ودع Hotspot يقوم بسحره.نادرًا ما نواجه مشكلات في الأداء حول تعليمات برمجية كهذه - عندما يأتي إصدار VM جديد، ستحصل على جميع مزايا السرعة الإضافية وما إلى ذلك.

بقدر ما أحب مجموعات جاكرتا، فإنها لا تدعم الأدوية العامة وتستخدم 1.4 كشاشة LCD.أنا حذر من مجموعات Google لأنها مدرجة كمستوى دعم ألفا!

لم أر أي حل يتابع مدير تعقيد الفضاء.إذا كانت قائمة الأعداد الصحيحة لديها عدد كبير من العناصر ، فهذا مشكلة كبيرة.

It will be really good to remove the integer from the List<Integer> and free
the space, once it's added to List<String>.

يمكننا استخدام التكرار لتحقيق نفس الشيء.

    List<Integer> oldList = new ArrayList<>();
    oldList.add(12);
    oldList.add(14);
    .......
    .......

    List<String> newList = new ArrayList<String>(oldList.size());
    Iterator<Integer> itr = oldList.iterator();
    while(itr.hasNext()){
        newList.add(itr.next().toString());
        itr.remove();
    }

أردت فقط أن أتناغم مع حل موجه للمشكلة للمشكلة.

إذا قمت بتصميم كائنات المجال، فإن الحل يكمن في كائنات المجال.المجال هنا عبارة عن قائمة من الأعداد الصحيحة التي نريد قيم سلسلة لها.

أسهل طريقة هي عدم تحويل القائمة على الإطلاق.

ومع ذلك، من أجل التحويل دون تحويل، قم بتغيير القائمة الأصلية للأعداد الصحيحة إلى قائمة القيمة، حيث تبدو القيمة كما يلي...

class Value {
    Integer value;
    public Integer getInt()
    {
       return value;
    }
    public String getString()
    {
       return String.valueOf(value);
    }
}

سيكون هذا أسرع وسيستهلك ذاكرة أقل من نسخ القائمة.

حظ سعيد!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top