วิธีที่ง่ายที่สุดในการแปลง List เป็น Set ใน Java


คำตอบ:


1065
Set<Foo> foo = new HashSet<Foo>(myList);

3
ในขณะที่คำตอบที่ถูกต้องนี้ไม่มีบริบททางเทคนิคเพียงพอที่จะรับประกันว่าเป็นคำตอบที่ดีที่สุด / ยอมรับเนื่องจากมีข้อผิดพลาดที่นี่ขึ้นอยู่กับการใช้งานของSetและMapหนึ่งกำลังใช้; HashSetมีการสันนิษฐานว่าที่นี่
Madbreaks

145

ฉันเห็นด้วยกับ sepp2k แต่มีรายละเอียดอื่น ๆ ที่อาจมีความสำคัญ:

new HashSet<Foo>(myList);

จะให้ชุดที่ไม่เรียงลำดับซึ่งไม่มีการทำซ้ำ ในกรณีนี้การทำซ้ำจะถูกระบุโดยใช้วิธี. equals () บนวัตถุของคุณ ซึ่งทำร่วมกับเมธอด. hashCode () (สำหรับข้อมูลเพิ่มเติมเกี่ยวกับความเท่าเทียมดูที่นี่ )

ทางเลือกที่ให้ชุดเรียงเป็น:

new TreeSet<Foo>(myList);

สิ่งนี้จะทำงานได้ถ้า Foo ใช้การเปรียบเทียบได้ หากไม่เป็นเช่นนั้นคุณอาจต้องการใช้เครื่องมือเปรียบเทียบ:

Set<Foo> lSet = new TreeSet<Foo>(someComparator);
lSet.addAll(myList);

สิ่งนี้ขึ้นอยู่กับ comparTo () (จากส่วนต่อประสานที่เปรียบเทียบได้) หรือ compar () (จากตัวเปรียบเทียบ) เพื่อให้แน่ใจว่ามีความเป็นเอกลักษณ์ ดังนั้นถ้าคุณสนใจเรื่องความเป็นเอกลักษณ์ให้ใช้ HashSet หากคุณหลังจากเรียงลำดับแล้วให้พิจารณาชุด TreeSet (โปรดจำไว้ว่า: ปรับให้เหมาะสมในภายหลัง!) หากประสิทธิภาพของเวลาใช้ HashSet หากประสิทธิภาพของพื้นที่มีความสำคัญให้ดูที่ TreeSet โปรดทราบว่าการติดตั้งและแผนที่มีประสิทธิภาพมากขึ้นผ่านทาง Trove (และที่ตั้งอื่น ๆ )


ขอบคุณที่รวมกรณีการใช้เครื่องมือเปรียบเทียบแบบกำหนดเองไว้ด้วย!
Justin Papez

70

ถ้าคุณใช้ไลบรารีGuava :

Set<Foo> set = Sets.newHashSet(list);

หรือดีกว่า:

Set<Foo> set = ImmutableSet.copyOf(list);

2
ทำไม ImmutableSet.copyOf ถึงดีกว่า?
user672009

1
newHashSet () ของ Guava มีข้อได้เปรียบอะไรบ้างเหนือกว่า Java new HashSet () พื้นฐาน
Nelda.techspiress

@ Nelda.techspiress javadocพูดถึงเมื่อวิธีควรหรือไม่ควรใช้ สังเกตส่วนสุดท้าย: วิธีนี้ไม่ได้มีประโยชน์มากและมีแนวโน้มที่จะถูกเลิกใช้ในอนาคต ถึงแม้ว่าฉันจะรู้สึกประหลาดใจเล็กน้อยที่ความมั่นคงไม่ได้ถูกกล่าวถึงว่าเป็นปัจจัยอย่างที่มันเป็นImmutableSet.of()เช่น แก้ไข: มันอาจจะไม่เป็นปัจจัยเพราะทุก overloads จะไม่จำเป็น
shmosel

1
เฮ้ขอบคุณสำหรับการอ้างอิง @shmosel แต่ฉันมองหาความรู้เชิงประจักษ์มากขึ้น สำหรับผู้ที่ใช้ Guava ทำไม Guava ถึงเลือก HashSet
Nelda.techspiress

27

การใช้ java 8 คุณสามารถใช้สตรีม:

List<Integer> mylist = Arrays.asList(100, 101, 102);
Set<Integer> myset = mylist.stream().collect(Collectors.toSet()));

10
คุณตรวจสอบบทลงโทษนี้หรือไม่? นี่จะทำซ้ำ + iterator, HashSet ใหม่ () และจากนั้นสำหรับแต่ละรายการการเรียกใช้ addAll () ในชุดใหม่ โดยรวม cca 5 วัตถุที่สร้างขึ้นเพื่อสิ่งที่ง่ายเหมือน HashSet ใหม่ (รายการ)
Agoston Horvath

1
@AgostonHorvath ขอบคุณสำหรับความคิดเห็นของคุณ เดิมทีฉันกำลังมองหาข้อมูลนั้นเมื่อฉันมาที่นี่
TheRealChx101

17
Set<E> alphaSet  = new HashSet<E>(<your List>);

หรือตัวอย่างที่สมบูรณ์

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class ListToSet
{
    public static void main(String[] args)
    {
        List<String> alphaList = new ArrayList<String>();
        alphaList.add("A");
        alphaList.add("B");
        alphaList.add("C");
        alphaList.add("A");
        alphaList.add("B");
        System.out.println("List values .....");
        for (String alpha : alphaList)
        {
            System.out.println(alpha);
        }
        Set<String> alphaSet = new HashSet<String>(alphaList);
        System.out.println("\nSet values .....");
        for (String alpha : alphaSet)
        {
            System.out.println(alpha);
        }
    }
}

1
+1 สำหรับตัวอย่างโค้ดแบบสมบูรณ์ หมายเหตุเพิ่มเติมที่นี่อีกอย่างหนึ่งคือการแฮ็ชไม่รับประกันว่าจะเหมือนเดิมจากการรัน ซึ่งหมายความว่ารายการที่พิมพ์หลังจาก 'ตั้งค่า ..... ' อาจเป็น 'ABC' หนึ่งการทำงานและ 'CBA' การทำงานอื่น ดังที่ฉันได้กล่าวไว้ในคำตอบของฉันคุณสามารถใช้ชุดต้นไม้เพื่อรับการสั่งซื้อที่มั่นคง อีกตัวเลือกหนึ่งคือการใช้ LinkedHashSet ซึ่งจะจดจำคำสั่งที่มีการเพิ่มรายการไว้
Spina

8

ฉันจะทำการตรวจสอบ Null ก่อนที่จะแปลงเป็นชุด

if(myList != null){
Set<Foo> foo = new HashSet<Foo>(myList);
}

3
หรือSet<Foo> foo = myList == null ? Collections.emptySet() : new HashSet<Foo>(myList);
vegemite4me

6

คุณสามารถแปลงList<>เป็นSet<>

Set<T> set=new HashSet<T>();

//Added dependency -> If list is null then it will throw NullPointerExcetion.

Set<T> set;
if(list != null){
    set = new HashSet<T>(list);
}

ฉันคิดว่าคุณหมายถึงการคัดเลือกมันจาก List to Set
Simon

6

สำหรับ Java 8 มันง่ายมาก:

List < UserEntity > vList= new ArrayList<>(); 
vList= service(...);
Set<UserEntity> vSet= vList.stream().collect(Collectors.toSet());

"ของจริง" Java 8 น่าจะใช้new ArrayList<>();-)
JR

6

Java - addAll

set.addAll(aList);

Java - วัตถุใหม่

new HashSet(list)

Java-8

list.stream().collect(Collectors.toSet());

ใช้ Guva

 Sets.newHashSet(list)

Apache Commons

CollectionUtils.addAll(targetSet, sourceList);

Java 10

var set = Set.copyOf(list);

5

อย่าลืมเพื่อนที่ค่อนข้างใหม่ของเรา สตรีม API หากคุณต้องการรายการ preprocess ก่อนที่จะแปลงเป็นชุดมันจะดีกว่าถ้ามีสิ่งต่อไปนี้:

list.stream().<here goes some preprocessing>.collect(Collectors.toSet());

4

วิธีที่ดีที่สุดในการใช้ตัวสร้าง

Set s= new HashSet(list);

ใน java 8 คุณสามารถใช้ stream api ::

Set s= list.stream().collect(Collectors.toSet());

3

มีหลายวิธีที่จะได้รับSetเป็น:

    List<Integer> sourceList = new ArrayList();
    sourceList.add(1);
    sourceList.add(2);
    sourceList.add(3);
    sourceList.add(4);

    // Using Core Java
    Set<Integer> set1 = new HashSet<>(sourceList);  //needs null-check if sourceList can be null.

    // Java 8
    Set<Integer> set2 = sourceList.stream().collect(Collectors.toSet());
    Set<Integer> set3 = sourceList.stream().collect(Collectors.toCollection(HashSet::new));

    //Guava
    Set<Integer> set4 = Sets.newHashSet(sourceList);

    // Apache commons
    Set<Integer> set5 = new HashSet<>(4);
    CollectionUtils.addAll(set5, sourceList);

เมื่อเราใช้มันกลับชุดและตามเอกสาร:Collectors.toSet() There are no guarantees on the type, mutability, serializability, or thread-safety of the Set returnedถ้าเราต้องการได้รับHashSetแล้วเราสามารถใช้ทางเลือกอื่นเพื่อรับชุด (ตรวจสอบset3)


3

ด้วย Java 10 ตอนนี้คุณสามารถใช้Set#copyOfเพื่อแปลง a List<E>เป็น unmodifiable ได้อย่างง่ายดายSet<E>:

ตัวอย่าง:

var set = Set.copyOf(list);

เก็บไว้ในใจว่านี่คือการดำเนินการเรียงลำดับและnullองค์ประกอบที่จะไม่ได้NullPointerExceptionรับอนุญาตเป็นมันจะโยน

หากคุณต้องการให้มันแก้ไขได้เพียงแค่ส่งมันไปยังการสร้างการSetดำเนินการ


2

โซลูชันที่ยืดหยุ่นของ Java 8 เพิ่มเติมด้วย Optional.ofNullable

Set<Foo> mySet = Optional.ofNullable(myList).map(HashSet::new).orElse(null);

2

หากคุณใช้Eclipse Collections :

MutableSet<Integer> mSet = Lists.mutable.with(1, 2, 3).toSet();
MutableIntSet mIntSet = IntLists.mutable.with(1, 2, 3).toSet();

MutableSetอินเตอร์เฟซที่ยื่นออกมาjava.util.Setในขณะที่MutableIntSetอินเตอร์เฟซไม่ได้ นอกจากนี้คุณยังสามารถแปลงIterableเป็นคลาสที่Setใช้จากSetsโรงงาน

Set<Integer> set = Sets.mutable.withAll(List.of(1, 2, 3));

มีคำอธิบายเพิ่มเติมในโรงงานที่ไม่แน่นอนที่มีอยู่ในคอลเลกชัน Eclipse เป็นที่นี่

หากคุณต้องการImmutableSetจากListคุณสามารถใช้Setsโรงงานดังต่อไปนี้:

ImmutableSet<Integer> immutableSet = Sets.immutable.withAll(List.of(1, 2, 3))

หมายเหตุ: ฉันเป็นคอมมิชชันสำหรับ Eclipse Collections


0

โปรดจำไว้ว่าการแปลงจากรายการเป็นชุดจะลบรายการซ้ำออกจากคอลเลกชันเนื่องจากรายการรองรับรายการซ้ำ แต่ชุดไม่รองรับรายการซ้ำใน Java

การแปลงโดยตรง:วิธีที่ใช้กันทั่วไปและง่ายที่สุดในการแปลงรายการเป็นชุด

// Creating a list of strings
List<String> list = Arrays.asList("One", "Two", "Three", "Four");

// Converting a list to set
Set<String> set = new HashSet<>(list);

Apache Commons Collections:คุณยังสามารถใช้ API ชุดคำสั่งทั่วไปในการแปลงรายการเป็นชุด: -

// Creating a list of strings
List<String> list = Arrays.asList("One", "Two", "Three", "Four");

// Creating a set with the same number of members in the list 
Set<String> set = new HashSet<>(4);

// Adds all of the elements in the list to the target set
CollectionUtils.addAll(set, list);

การใช้สตรีม:อีกวิธีคือการแปลงรายการที่กำหนดเป็นสตรีมจากนั้นสตรีมเป็นชุด: -

// Creating a list of strings 
List<String> list = Arrays.asList("One", "Two", "Three", "Four"); 

// Converting to set using stream 
Set<String> set = list.stream().collect(Collectors.toSet()); 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.