indexOf ของ Java อยู่ที่ไหน?


199

ฉันต้องคิดถึงบางสิ่งที่ชัดเจนมาก แต่ฉันได้ทำการค้นหาไปแล้วทั้งหมดและไม่สามารถหาวิธีนี้ได้

คำตอบ:


234

มีสองวิธีในการทำให้สิ่งนี้สำเร็จโดยใช้Arraysคลาสยูทิลิตี้

หากอาร์เรย์ไม่ได้ถูกจัดเรียงและไม่ได้เป็นอาร์เรย์ของดั้งเดิม:

java.util.Arrays.asList(theArray).indexOf(o)

หากอาร์เรย์เป็นพื้นฐานและไม่ได้เรียงหนึ่งควรใช้วิธีการแก้ปัญหาที่นำเสนอโดยหนึ่งในคำตอบอื่น ๆ เช่นKerem Baydoğanของ , แอนดรู McKinlay ของหรือMishax ของ รหัสข้างต้นจะรวบรวมแม้ว่าtheArrayจะเป็นแบบดั้งเดิม (อาจเปล่งคำเตือน) แต่คุณจะได้รับผลลัพธ์ที่ไม่ถูกต้องโดยสิ้นเชิงอย่างไรก็ตาม

หากมีการจัดเรียงอาร์เรย์คุณสามารถใช้ประโยชน์จากการค้นหาแบบไบนารีเพื่อประสิทธิภาพ:

java.util.Arrays.binarySearch(theArray, o)

3
ฉันค่อนข้างมั่นใจว่าคำตอบนี้ผิดอย่างน้อยสำหรับ java 1.6: download.oracle.com/javase/6/docs/api/java/util/ … asList จะแปลงรายการอาร์กิวเมนต์เป็นรายการไม่ใช่อาร์กิวเมนต์เอง
Alexandru

11
@Alexandru Ellipsis จัดการน้ำตาลได้ หากคุณมีการพิมพ์อาร์กิวเมนต์T...ประเภทของเวลาทำงานจริงของการโต้แย้งคือT[]และผ่านพารามิเตอร์ศูนย์หรือมากกว่าประเภทTผลลัพธ์ผลลัพธ์ในพวกเขาจะถูกห่อเป็นอาร์เรย์ที่สร้างขึ้นใหม่และผ่าน หากพารามิเตอร์ที่ส่งผ่านมีประเภทอยู่แล้วT[]น้ำตาลประโยคจะถูกข้ามไป
Jeffrey Hantin

7
ฉันเห็นประเด็นของคุณ การแก้ปัญหา ( .indexOf) ไม่ถูกต้องสำหรับ primitives แม้ว่า
Alexandru

53
เนื่องจากไม่มีใครพูดถึง: Arrays.asList ใช้อาร์เรย์ที่มีอยู่แล้วเป็นข้อมูลสำรอง (เช่นไม่มีข้อกังวลเกี่ยวกับสำเนาที่ถูกสร้างขึ้น)
Joshua Goldberg

4
@Notinlist พวกจาวาก็คิดเช่นกัน ใช้เพื่อค้นหาองค์ประกอบอยู่ในช่วงที่Arrays.toList(list).sublist(from,to).indexOf(o) [from, to)
Mario Carneiro

62

Array ไม่มีindexOf()วิธีการ

บางทีวิธี Apache Commons Lang ArrayUtilsนี้เป็นสิ่งที่คุณกำลังมองหา

import org.apache.commons.lang3.ArrayUtils;

String[] colours = { "Red", "Orange", "Yellow", "Green" };

int indexOfYellow = ArrayUtils.indexOf(colours, "Yellow");

Eclipse ไม่พบไลบรารีนำเข้านี้
Omore

21

สำหรับ primitives หากคุณต้องการหลีกเลี่ยงการชกมวยGuavaมีผู้ช่วยสำหรับอาร์เรย์ดั้งเดิมเช่นInts.indexOf (int [] อาร์เรย์เป้าหมาย int)


โซลูชันอื่น ๆ ทั้งหมดสร้างสตริงหรือรายการใหม่หรือเพียงแค่จัดการองค์ประกอบเดียว Chars.indexOf ของ Guava ช่วยให้คุณรับดัชนีของอาร์เรย์ในอาร์เรย์ นี่คือทางออกที่ถูกต้อง
HappyEngineer

18

ไม่มีเลย ใช้java.util.List* หรือคุณสามารถเขียนของคุณเองindexOf():

public static <T> int indexOf(T needle, T[] haystack)
{
    for (int i=0; i<haystack.length; i++)
    {
        if (haystack[i] != null && haystack[i].equals(needle)
            || needle == null && haystack[i] == null) return i;
    }

    return -1;
}

* คุณสามารถสร้างจากอาร์เรย์โดยใช้ Arrays#asList()


2
การใช้Tทำให้เข้าใจผิด มันไม่ได้ให้ความปลอดภัยประเภทใด ๆ และง่ายต่อการเข้าใจผิดมันเป็นประเภทที่ปลอดภัย ... ใช้งานได้ดีขึ้น Object
Venkata Raju

4
@VenkataRaju โดยใช้ T here บังคับให้พารามิเตอร์เมธอดทั้งสองเป็นประเภทเดียวกัน นั่นมีประโยชน์
gonadarian

5
@gonadarian ไม่จริง ทั้งสองคอมไพล์เหล่านี้เพียงแค่ปรับ: indexOf("str", new Object[] {});,indexOf(new Object(), new String[] {});
Venkata Raju

1
@VenkataRaju ใช่จริง ๆ ตัวอย่างของคุณไม่ได้พิสูจน์อะไรเลยเนื่องจาก String เป็นวัตถุ ... ดังนั้นแน่นอนว่าอาร์เรย์วัตถุอาจมีสตริงที่คุณอาจต้องการค้นหาดัชนี

1
@ ghert85 อีกตัวอย่าง: indexOf("str", new Date[] {}),indexOf(new Date(), new String[] {})
Venkata Raju

15

ไม่เหมือนใน C # ที่คุณมีเมธอดArray.IndexOfและ JavaScript ที่คุณมีเมธอดindexOf , API ของ Java ( ArrayและArraysโดยเฉพาะคลาส) ไม่มีวิธีการดังกล่าว

เมธอดนี้ indexOf (พร้อมกับส่วนเสริม lastIndexOf) ถูกกำหนดในอินเตอร์เฟสjava.util.List โปรดทราบว่า indexOf และ lastIndexOf จะไม่โหลดมากเกินไปและใช้วัตถุเป็นพารามิเตอร์เท่านั้น

ถ้าอาเรย์ของคุณถูกจัดเรียงคุณจะโชคดีเพราะคลาสอาเรย์กำหนดชุดของโอเวอร์โหลดของวิธีการค้นหาแบบไบนารีที่จะค้นหาดัชนีขององค์ประกอบที่คุณกำลังมองหาด้วยประสิทธิภาพที่ดีที่สุด (O (log n) แทน O (n ) สิ่งหลังคือสิ่งที่คุณคาดหวังได้จากการค้นหาตามลำดับที่ทำโดย indexOf) มีข้อควรพิจารณาสี่ประการ:

  1. อาเรย์จะต้องเรียงลำดับตามลำดับธรรมชาติหรือตามลำดับของ Comparator ที่คุณจัดให้เป็นอาร์กิวเมนต์หรืออย่างน้อยที่สุดองค์ประกอบทั้งหมดที่เป็น "น้อยกว่า" คีย์จะต้องมาก่อนองค์ประกอบในอาร์เรย์และองค์ประกอบทั้งหมดที่ คือ "มากกว่า" คีย์ต้องมาหลังจากองค์ประกอบนั้นในอาร์เรย์

  2. โดยปกติการทดสอบที่คุณทำกับ indexOf เพื่อตรวจสอบว่าคีย์อยู่ในอาร์เรย์หรือไม่ (ตรวจสอบว่าค่าส่งคืนไม่ใช่ -1) จะไม่ถือด้วย binarySearch คุณต้องตรวจสอบว่าค่าส่งคืนไม่น้อยกว่าศูนย์เนื่องจากค่าที่ส่งคืนจะระบุว่าไม่มีคีย์ แต่จะมีดัชนีซึ่งคาดว่าจะเกิดขึ้นหากมีอยู่

  3. หากอาร์เรย์ของคุณมีองค์ประกอบหลายอย่างที่เท่ากับกุญแจสิ่งที่คุณได้รับจาก binarySearch จะไม่ถูกกำหนด สิ่งนี้แตกต่างจาก indexOf ที่จะคืนค่าการเกิดครั้งแรกและ lastIndexOf ที่จะคืนค่าการเกิดครั้งสุดท้าย

  4. อาเรย์ของบูลีนอาจปรากฏขึ้นเพื่อเรียงลำดับถ้ามันมีเท็จทั้งหมดและจากนั้นความจริงทั้งหมด แต่ไม่นับ ไม่มีการแทนที่ของวิธีการ binarySearch ที่ยอมรับอาร์เรย์ของบูลีนและคุณจะต้องทำสิ่งที่ชาญฉลาดถ้าคุณต้องการประสิทธิภาพ O (log n) เมื่อตรวจสอบว่าจริงแรกปรากฏในอาร์เรย์เช่นการใช้อาร์เรย์ของ บูลีนและค่าคงที่ Boolean.FALSE และ Boolean.TRUE

ถ้าอาเรย์ของคุณไม่ได้ถูกจัดเรียงและไม่ใช่ประเภทดึกดำบรรพ์คุณสามารถใช้เมธอด indexOf และ lastIndexOf ของรายการโดยเรียกใช้เมธอด asListเมธอดของ java.util.Arrays วิธีนี้จะส่งคืน wrapper อินเทอร์เฟซ AbstractList รอบอาร์เรย์ของคุณ มันเกี่ยวข้องกับค่าใช้จ่ายน้อยที่สุดเพราะมันไม่ได้สร้างสำเนาของอาร์เรย์ ดังที่ได้กล่าวมาแล้ววิธีนี้ไม่ได้รับการโอเวอร์โหลดดังนั้นจะใช้งานได้กับอาร์เรย์ของประเภทการอ้างอิงเท่านั้น

หากอาร์เรย์ของคุณไม่ได้ถูกจัดเรียงและประเภทของอาร์เรย์นั้นเป็นแบบดั้งเดิมคุณจะไม่โชคดีกับ Java API เขียนของคุณเองสำหรับลูปหรือวิธียูทิลิตี้สแตติกของคุณเองซึ่งแน่นอนจะมีข้อได้เปรียบประสิทธิภาพมากกว่าวิธี asList ที่เกี่ยวข้องกับค่าใช้จ่ายบางส่วนของการเริ่มต้นวัตถุ ในกรณีที่คุณกังวลว่าการเขียนแรงเดรัจฉานสำหรับลูปที่วนซ้ำองค์ประกอบทั้งหมดของอาเรย์ไม่ใช่วิธีที่สวยงามให้ยอมรับว่านั่นคือสิ่งที่ Java API ทำเมื่อคุณเรียก indexOf คุณสามารถทำสิ่งนี้:

public static int indexOfIntArray(int[] array, int key) {
    int returnvalue = -1;
    for (int i = 0; i < array.length; ++i) {
        if (key == array[i]) {
            returnvalue = i;
            break;
        }
    }
    return returnvalue;
}

หากคุณต้องการหลีกเลี่ยงการเขียนวิธีการของคุณเองที่นี่ให้ลองใช้หนึ่งในกรอบการพัฒนาเช่น Guava มีคุณสามารถค้นหาการดำเนินการของindexOfและlastIndexOf


11

Java ArrayListมีindexOfวิธีการ อาร์เรย์ Java ไม่มีวิธีการดังกล่าว


26
ไม่ได้เป็นเพียงArrayList- ทุก Java มีList indexOf()
Matt Ball

6

ฉันไม่จำ "indexOf" ในอาร์เรย์นอกเหนือจากการเขียนโค้ดด้วยตัวคุณเอง ... แม้ว่าคุณอาจใช้วิธีการหนึ่งในหลาย ๆjava.util.Arrays#binarySearch(...)วิธี (ดูArray javadoc ) ถ้าอาร์เรย์ของคุณมีประเภทดั้งเดิม


5

รายการอินเตอร์เฟสมีเมธอด indexOf () และคุณสามารถรับรายการจากอาเรย์ของคุณได้ด้วยเมธอด asList () ของ Array นอกจากนั้น Array เองก็ไม่มีวิธีดังกล่าว มันมีวิธี binarySearch () สำหรับอาร์เรย์ที่เรียงลำดับ


4

อาร์เรย์ไม่มีวิธีการดังกล่าว อย่างไรก็ตาม List ทำ: indexOf


2
ไม่ได้เป็นเพียงArrayList- ทุก Java มีList indexOf()
Matt Ball

ใช่ฉันเพียงแค่ระบุ ArrayList เพราะนั่นอาจจะเป็นสิ่งที่ใกล้เคียงกับสิ่งที่ OP ถูกมองหา :)
อิกอร์



0

คำตอบของJeffrey Hantinนั้นดี แต่มันมีข้อ จำกัด บางอย่างถ้ามันทำเช่นนี้หรืออย่างอื่น ...

คุณสามารถเขียนวิธีการขยายของคุณเองและมันทำงานได้ตามที่คุณต้องการ

Lists.indexOf(array, x -> item == x); // compare in the way you want

และนี่คือส่วนขยายของคุณ

public final class Lists {
    private Lists() {
    }

    public static <T> int indexOf(T[] array, Predicate<T> predicate) {
        for (int i = 0; i < array.length; i++) {
            if (predicate.test(array[i])) return i;
        }
        return -1;
    }

    public static <T> int indexOf(List<T> list, Predicate<T> predicate) {
        for (int i = 0; i < list.size(); i++) {
            if (predicate.test(list.get(i))) return i;
        }
        return -1;
    }

    public interface Predicate<T> {
        boolean test(T t);
    }
}

-4
int findIndex(int myElement, int[] someArray){
 int index = 0;
 for(int n: someArray){
   if(myElement == n) return index;
   else index++;
 }
}

หมายเหตุ: คุณสามารถใช้วิธีนี้สำหรับอาร์เรย์ของ int ประเภทคุณยังสามารถใช้อัลกอริทึมนี้สำหรับประเภทอื่นที่มีการเปลี่ยนแปลงเล็กน้อย


1
-1: ก่อนอื่นสิ่งนี้จะกลายเป็นอาร์เรย์ดั้งเดิมที่จะเรียงซึ่งเราอาจไม่ต้องการ ข้อที่สองมันให้คำตอบว่าอาร์ทีเรียงลำดับอาเรย์ไม่ใช่อาเรย์ดั้งเดิมซึ่งน่าจะเป็นสิ่งที่เราต้องการ (ถ้าเราต้องการคำตอบที่อาเรย์จัดเรียงอาร์ที ประการที่สามเนื่องจากการเรียงลำดับคือ O (n log n) นี่จะช้ากว่าการผ่านอาร์เรย์เป็นเส้นตรง ดังนั้นคำตอบนี้ไม่ถูกต้องและไม่มีประสิทธิภาพ
เจมี่

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