2010-04-15 2 views
29

목록 또는 집합의 모든 요소를 ​​소문자로 만드는 가장 효율적인 방법은 무엇입니까? 목록컬렉션의 모든 요소를 ​​효율적으로 소문자로 만드는 방법은 무엇입니까?

내 생각 :

final List<String> strings = new ArrayList<String>(); 
strings.add("HELLO"); 
strings.add("WORLD"); 

for(int i=0,l=strings.size();i<l;++i) 
{ 
    strings.add(strings.remove(0).toLowerCase()); 
} 

더 나은, 더 빠른 방법이 있나요? 이 예제는 Set에 대해 어떻게 생겼을까요? 현재 Set (또는 List)의 각 요소에 작업을 적용 할 방법이 없기 때문에 추가 임시 Set을 만들지 않고도 작업을 수행 할 수 있습니까? 이 같은

뭔가 좋은 것 :

Set<String> strings = new HashSet<String>(); 
strings.apply(
    function (element) 
    { this.replace(element, element.toLowerCase();) } 
); 

감사합니다,

답변

22

목록에 대해서는 상당히 깨끗한 솔루션처럼 보입니다. 그것은 특정 목록 구현이 목록의 순회 (선형 시간 - 및 문자열 교체)에 일정한 시간에 최적 인 구현을 제공하는 데 사용되어야합니다.

public static void replace(List<String> strings) 
{ 
    ListIterator<String> iterator = strings.listIterator(); 
    while (iterator.hasNext()) 
    { 
     iterator.set(iterator.next().toLowerCase()); 
    } 
} 

내가 세트와 함께 올 수있는 최선이다. 다른 사람들이 말했듯이, 작업은 여러 가지 이유로 세트에서 제자리에서 수행 될 수 없습니다. 소문자 문자열은 대체 할 문자열과 다른 위치에 배치해야 할 수도 있습니다. 또한, 이미 소문자로 된 문자열이 이미 추가 된 다른 소문자 문자열과 동일하면 집합에 소문자 문자열이 전혀 추가되지 않을 수 있습니다 (예 : "HELLO"및 "Hello"둘 다 "hello"를 생성합니다. 한 번만 세트에 추가 할 수 있음).

public static void replace(Set<String> strings) 
{ 
    String[] stringsArray = strings.toArray(new String[0]); 
    for (int i=0; i<stringsArray.length; ++i) 
    { 
     stringsArray[i] = stringsArray[i].toLowerCase(); 
    } 
    strings.clear(); 
    strings.addAll(Arrays.asList(stringsArray)); 
} 
+0

첫 번째 솔루션을 참조하십시오 : 어떻게 ListIterator를 List로 반환합니까? –

+0

@rookie, 질문이 명확하지 않습니다. ListIterator를 List로 사용하는 방법을 묻고 있습니까? 그렇다면, 그럴 수 없습니다. 반복자는 콜렉션이 아니라 하나에 대한 포인터입니다. – Jeremy

1

이 빠르게 아마도 :

for(int i=0,l=strings.size();i<l;++i) 
{ 
    strings.set(i, strings.get(i).toLowerCase()); 
} 
+2

빨라지지만 성능은''LinkedList' 대한 O (N^2) '이다. –

+0

예. 너의 경우, 반대는 사실이다. –

+0

죄송합니다. 원래 알고리즘의 경우 반대입니다. –

4

음, 때문에 두 가지 사실에 실제 우아한 해결책은 없다 :

  • Java에서s는 변경 불가능합니다.
  • Java는 함수형 언어에서와 마찬가지로 실제 멋진 map(f, list) 함수를 제공하지 않습니다.

점근적으로 말하면 현재 방법보다 더 나은 실행 시간을 얻을 수 없습니다. toLowerCase()을 사용하여 새 문자열을 만들어야하며 목록에서 직접 반복하고 각각의 새로운 소문자 문자열을 생성하여 기존 문자열로 대체해야합니다.

+0

그리고 무엇보다 Java에 람다도 없습니다 (지금까지) ... – Xaerxess

0

문자열을 세트로 변경하면 다른 콜렉션을 만들지 않고 조작을 수행 할 수 있다고 생각하지 않습니다. 이는 반복자 또는 각 루프를 사용하여 Set를 반복 할 수 있고 예외를 throw하는 동안 새 객체를 삽입 할 수 없기 때문입니다.

13

당신은 구글 컬렉션과 함께이 작업을 수행 할 수 있습니다

Collection<String> lowerCaseStrings = Collections2.transform(strings, 
     new Function<String, String>() { 
      public String apply(String str) { 
       return str.toLowerCase(); 
      } 
     } 
    ); 
0

허용 (마 T. Staebler의) 솔루션의 반복자 방법을 참조. 이 메서드보다 ListIterator를 어떻게 사용하면 좋을까요?하지만, 자바 8

public static Set<String> replace(List<String> strings) { 
    Set<String> set = new HashSet<>(); 
    for (String s: strings) 
     set.add(s.toLowerCase()); 
    return set; 
} 
59

또 다른 솔루션 :

List<String> result = strings.stream() 
          .map(String::toLowerCase) 
          .collect(Collectors.toList()); 
+0

나중에 Java 8을 얻은 경우이 스레드의 최상의 솔루션입니다. – liltitus27

0
나는 비슷한 물건을 찾고 있었다,하지만 내 ArrayList를 객체가 GENERIC과로 선언되지 않았기 때문에 붙어 있었다

는 원시 목록 어딘가에서 사용할 수있었습니다. 나는 방금 ArrayList "_products"개체를 얻고있었습니다. 그럼, 내가 한 것은 아래에 언급하고 완벽하게 :: 나를 위해 일한

나는 단지 문자열을 얻고 있었다, 나는 먼저 (내 사용할 수 _products을 가져 갔고, GENERIC 목록 개체를 만들어
List<String> dbProducts = _products; 
    for(int i = 0; i<dbProducts.size(); i++) { 
     dbProducts.add(dbProducts.get(i).toLowerCase());   
    } 

같은 경우) non-generic ArrayList 개체 때문에 이전에 작동하지 않았던 목록 요소에 toLowerCase() 메서드를 적용했습니다.

그리고 우리가 여기에서 사용하는 방법 와 toLowerCase()문자열 클래스이다.

문자열 java.lang.String.toLowerCase()

하지 ArrayList를 또는 객체 클래스의.

잘못 입력했는지 확인하십시오. JAVA의 초보자가 안내를 구합니다. :)

0

는 JAVA 8 병렬 스트림을 사용하여이는`ArrayList` 괜찮지

List<String> output= new ArrayList<>(); 
List<String> input= new ArrayList<>(); 
input.add("A"); 
input.add("B"); 
input.add("C"); 
input.add("D"); 
input.stream().parallel().map((item) -> item.toLowerCase()) 
      .collect(Collectors.toCollection(() -> output)); 
+0

결과의 문자열 순서가 달라집니다. –

관련 문제