.asSet (…) มีอยู่ใน API ใด ๆ หรือไม่


111

ฉันกำลังมองหาวิธีง่ายๆในการสร้างชุด

Arrays.asList("a", "b" ...) สร้างไฟล์ List<String>

มีอะไรที่คล้ายกันสำหรับSet?



1
ไม่ใช่การสร้าง Set และการแปลง Array เป็น Set นั้นไม่เหมือนกัน
cahen

คำตอบ:


86

ตอนนี้ด้วย Java 8 คุณสามารถทำได้โดยไม่ต้องใช้เฟรมเวิร์กของบุคคลที่สาม:

Set<String> set = Stream.of("a","b","c").collect(Collectors.toSet());

ดูนักสะสม

สนุก!


4
ปัจจุบันด้วย Java 8 นี่อาจเป็นคำตอบที่ดีที่สุดเพราะไม่ได้ขึ้นอยู่กับไลบรารีของบุคคลที่สามและสามารถปรับให้เข้ากับประเภทคอลเล็กชันอื่น ๆ ได้อย่างง่ายดายดังนั้นฉันจึงตั้งค่านี้เป็นแบบที่ยอมรับ ขอบคุณมากสำหรับทุกคนสำหรับวิธีแก้ปัญหาที่ยอดเยี่ยมอื่น ๆ (btw ชุดนี้ไม่แน่นอน)
ประมาณ

3
ตอนนี้ใครบอกว่า Java มันเวอร์เกินไป? แน่นอนว่านี่คือคำตอบที่ดีที่สุด!
BobDoolittle

ขอบคุณมาก @BobDoolittle!
Mr. Anderson

2
สำหรับใครที่ใช้ java 9+ โปรดดูคำตอบของ Holly ด้านล่าง: stackoverflow.com/a/48025159/229743
Taylor

1
คำตอบที่ไร้ที่ติคุณแอนเดอร์สัน!
Gaurav

64

การใช้Guavaนั้นทำได้ง่ายๆดังนี้:

Set<String> mySet = ImmutableSet.<String> of("a", "b");

หรือสำหรับชุดที่ไม่แน่นอน:

Set<String> mySet = Sets.newHashSet("a", "b")

สำหรับประเภทข้อมูลเพิ่มเติมโปรดดูคู่มือผู้ใช้ Guava


มีรุ่นนี้ที่ไม่เปลี่ยนรูปหรือไม่?
cahen

3
@cahen ใช่: Sets.newHashSet("a", "b")หรือSets.newLinkedHashSet("a", "b")
Sean Patrick Floyd

1
ฉันเพิ่มตัวแปรที่ไม่แน่นอนให้กับคำตอบ
Michael Schmeißer

ที่จริงSets.newLinkedHashSet()ไม่มีลายเซ็นนั้นขออภัย
Sean Patrick Floyd

ฉันสามารถลบอาร์กิวเมนต์ประเภทหนึ่ง:Set<String> mySet = ImmutableSet.of("a", "b");
joshden

55

คุณสามารถใช้

new HashSet<String>(Arrays.asList("a","b"));

ฉันอยากจะทำสิ่งนี้จากนั้นใช้เวอร์ชันสตรีม ฉันสามารถนำเข้า "asList" แบบคงที่ได้โดยทำให้สิ่งนี้ละเอียดน้อยลง
Marcio Lucca

24

สำหรับกรณีพิเศษของเซตที่มีสมาชิกเป็นศูนย์หรือหนึ่งคนคุณสามารถใช้:

java.util.Collections.EMPTY_SET

และ:

java.util.Collections.singleton("A")

สำหรับกรณีพิเศษเหล่านี้น่าจะเป็นทางออกที่ดีที่สุดเนื่องจากใช้ java.util มาตรฐาน API
arcuri82

2
java.util.Collections.emptySet()คือในใจของฉันชอบมากกว่า EMPTY_SET เนื่องจากความปลอดภัยของประเภท จากความคิดเห็นในชั้นเรียน Collections:Unlike the like-named field, this method is parameterized.
แก้ไขเมื่อ

18

ตามที่คนอื่น ๆ กล่าวไว้ให้ใช้:

new HashSet<String>(Arrays.asList("a","b"));

เหตุผลนี้ไม่ได้มีอยู่ใน Java คือว่าArrays.asListผลตอบแทนที่เป็นรายการที่มีขนาดคงที่ในคำอื่น ๆ :

public static void main(String a[])
{
  List<String> myList = Arrays.asList("a", "b");
  myList.add("c");
}

ผลตอบแทน:

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.AbstractList.add(Unknown Source)
    at java.util.AbstractList.add(Unknown Source)

ไม่มีการใช้ JDK ของ "ขนาดคงที่" SetภายในArraysคลาส ทำไมคุณถึงต้องการสิ่งนี้? A Setรับประกันว่าไม่มีรายการที่ซ้ำกัน แต่ถ้าคุณพิมพ์ด้วยมือคุณไม่ควรใช้ฟังก์ชันนั้น ... และListมีวิธีการเพิ่มเติม อินเทอร์เฟซทั้งสองขยายCollectionและIterable.


อย่างที่คนอื่นบอกให้ใช้guavaถ้าคุณต้องการฟังก์ชั่นนี้จริงๆ - เนื่องจากไม่ได้อยู่ใน JDK ดูคำตอบของพวกเขา (โดยเฉพาะคำตอบของ Michael Schmeißer) เพื่อดูข้อมูลนั้น


3
นี่เป็นคำตอบที่ดีที่สุดเพราะมันชี้ให้เห็นว่า Arrays.asList () ทำอะไรได้จริง นักพัฒนาหลายคนดูเหมือนจะเชื่อว่า Arrays.asList () สร้าง java.util.ArrayList ในขณะที่มันสร้าง java.util.Arrays $ ArrayList (ซึ่งเปลี่ยนแปลงได้เพียงบางส่วนและมุมมองสดของอาร์เรย์ที่อยู่เบื้องหลัง)
Sean Patrick Floyd

1
เหตุผลที่ใครบางคนต้องการทำเช่นนี้สาเหตุที่พบบ่อยที่สุดในการสร้าง Set (หรือ List) ด้วยมือคือในชั้นทดสอบที่คุณกำลังส่งผ่านค่าการทดสอบ
Scott McIntyre

14

ใน Java 9 มีการเพิ่มฟังก์ชันที่คล้ายกันผ่านวิธีการของโรงงาน:

Set<String> oneLinerSet = Set.of("a", "b", ...);

(มีค่าเทียบเท่าListเช่นกัน)


ฉันลองแล้วและได้รับคำเตือนของคอมไพเลอร์ว่านี่ไม่ใช่เมธอด API
Philippe Gioseffi

นี่คือ doc Java ที่เกี่ยวข้อง: docs.oracle.com/javase/9/docs/api/java/util/Set.html เช่นเดียวกับการใช้ Java 9+ JDK คุณอาจต้องปรับ IDE ของคุณหรือสร้างเครื่องมือเพื่อใช้ความสอดคล้องกับ Java 9 (ตัวอย่างเช่นสำหรับ maven ขั้นตอนจะคล้ายกับที่นี่ แต่ตั้งค่าเป็น 1.9: stackoverflow.com/ คำถาม / 16798066 / … )
Holly Cummins

หวังว่าเราจะใช้ Java 9 ได้ .. เรากำลังอยู่ในอดีต! :(
jDub9

เป็นสิ่งที่ดี แต่มีข้อ จำกัด บางประการเกี่ยวกับขนาดของอาร์กิวเมนต์ ...
Radoslav Ivanov



2

นี่เป็นวิธีการเล็กน้อยที่คุณสามารถใช้ได้

  /**
   * Utility method analogous to {@link java.util.Arrays#asList(Object[])}
   *
   * @param ts
   * @param <T>
   * @return the set of all the parameters given.
   */
  @SafeVarargs
  @SuppressWarnings("varargs")
  public static <T> Set<T> asSet(T... ts) {
    return new HashSet<>(Arrays.asList(ts));
  }

1

อีกวิธีหนึ่งในการใช้ Java 8 และ enums ก็คือ:

Set<String> set = EnumSet.of(StandardOpenOption.CREATE, StandardOpenOption.READ);

ดูEnumSet

ฉันอยากจะแนะนำการวิเคราะห์ประสิทธิภาพระหว่างแนวทางนี้และ

Set<String> set = Stream.of(StandardOpenOption.CREATE, StandardOpenOption.READ).collect(Collectors.toSet());

เพราะถ้าคุณมีมากกว่าห้าองค์ประกอบ Javadoc ของรัฐที่วิธีการที่อาจจะมีปัญหาเรื่องประสิทธิภาพในขณะที่คุณสามารถมองเห็นใน Javadoc ของSet.Of (E, E ... )

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