001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      https://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.lang3.util;
019
020import java.util.ArrayList;
021import java.util.Iterator;
022import java.util.List;
023import java.util.Objects;
024import java.util.StringTokenizer;
025import java.util.stream.Stream;
026import java.util.stream.StreamSupport;
027
028import org.apache.commons.lang3.ArrayUtils;
029
030/**
031 * A {@link StringTokenizer} that implements {@link Iterable}{@code <String>} and conversion methods {@link #toList()} and {@link #toStream()}.
032 *
033 * @since 3.18.0
034 */
035public class IterableStringTokenizer extends StringTokenizer implements Iterable<String> {
036
037    /**
038     * Constructs a new instance like {@link StringTokenizer#StringTokenizer(String, String, boolean)}.
039     *
040     * @param str a string to be parsed.
041     * @exception NullPointerException if str is {@code null}.
042     */
043    public IterableStringTokenizer(final String str) {
044        super(str);
045    }
046
047    /**
048     * Constructs a new instance like {@link StringTokenizer#StringTokenizer(String, String, boolean)}.
049     *
050     * @param str   a string to be parsed.
051     * @param delim the delimiters.
052     * @exception NullPointerException if str is {@code null}.
053     */
054    public IterableStringTokenizer(final String str, final String delim) {
055        super(str, delim);
056    }
057
058    /**
059     * Constructs a new instance like {@link StringTokenizer#StringTokenizer(String, String, boolean)}.
060     *
061     * @param str          a string to be parsed.
062     * @param delim        the delimiters.
063     * @param returnDelims flag indicating whether to return the delimiters as tokens.
064     * @exception NullPointerException if str is {@code null}.
065     */
066    public IterableStringTokenizer(final String str, final String delim, final boolean returnDelims) {
067        super(str, delim, returnDelims);
068    }
069
070    @Override
071    public Iterator<String> iterator() {
072        return new Iterator<String>() {
073
074            @Override
075            public boolean hasNext() {
076                return hasMoreElements();
077            }
078
079            @Override
080            public String next() {
081                return Objects.toString(nextElement(), null);
082            }
083        };
084    }
085
086    /**
087     * Returns a new {@code String[]} containing the tokenizer elements.
088     *
089     * @return a new {@code String[]}.
090     */
091    public String[] toArray() {
092        return toList().toArray(ArrayUtils.EMPTY_STRING_ARRAY);
093    }
094
095    /**
096     * Returns a new {@link List} containing the tokenizer elements.
097     *
098     * @return a new {@link List}.
099     */
100    public List<String> toList() {
101        final List<String> list = new ArrayList<>();
102        forEach(list::add);
103        return list;
104    }
105
106    /**
107     * Returns a sequential stream on this Iterable instance.
108     *
109     * @return a sequential stream on this Iterable instance.
110     */
111    public Stream<String> toStream() {
112        return StreamSupport.stream(spliterator(), false);
113    }
114}