Wiem, że jest to trochę dla początkujących pytanie, ale czy istnieją odpowiedniki operacji na łańcuchach C # w Javie?
W szczególności mówię o String.Formati String.Join.
Wiem, że jest to trochę dla początkujących pytanie, ale czy istnieją odpowiedniki operacji na łańcuchach C # w Javie?
W szczególności mówię o String.Formati String.Join.
Odpowiedzi:
Obiekt Java String ma formatmetodę (od 1.5), ale nie ma żadnej joinmetody.
Aby uzyskać kilka przydatnych metod narzędziowych typu String, które nie zostały jeszcze uwzględnione, możesz użyć org.apache.commons.lang.StringUtils .
String.join()metodę.
String.format . Jeśli chodzi o dołączanie, musisz napisać własne:
static String join(Collection<?> s, String delimiter) {
StringBuilder builder = new StringBuilder();
Iterator<?> iter = s.iterator();
while (iter.hasNext()) {
builder.append(iter.next());
if (!iter.hasNext()) {
break;
}
builder.append(delimiter);
}
return builder.toString();
}
Powyższe pochodzi z http://snippets.dzone.com/posts/show/91
Guawa pochodzi z tej Joinerklasy .
import com.google.common.base.Joiner;
Joiner.on(separator).join(data);
Od wersji Java 8 join()jest teraz dostępna jako dwie metody klasowe w klasie String. W obu przypadkach ogranicznikiem jest pierwszy argument.
Możesz przekazać poszczególne CharSequenceargumenty jako dodatkowe argumenty :
String joined = String.join(", ", "Antimony", "Arsenic", "Aluminum", "Selenium");
// "Antimony, Arsenic, Alumninum, Selenium"
Lub możesz zdaćIterable<? extends CharSequence> :
List<String> strings = new LinkedList<String>();
strings.add("EX");
strings.add("TER");
strings.add("MIN");
strings.add("ATE");
String joined = String.join("-", strings);
// "EX-TER-MIN-ATE"
Java 8 dodaje również nową klasę StringJoiner, której możesz użyć w następujący sposób:
StringJoiner joiner = new StringJoiner("&");
joiner.add("x=9");
joiner.add("y=5667.7");
joiner.add("z=-33.0");
String joined = joiner.toString();
// "x=9&y=5667.7&z=-33.0"
TextUtils.join jest dostępny na Androida
Możesz również użyć zmiennych argumentów dla ciągów w następujący sposób:
String join (String delim, String ... data) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < data.length; i++) {
sb.append(data[i]);
if (i >= data.length-1) {break;}
sb.append(delim);
}
return sb.toString();
}
Jeśli chodzi o dołączanie, wydaje mi się, że może to wyglądać trochę mniej skomplikowane:
public String join (Collection<String> c) {
StringBuilder sb=new StringBuilder();
for(String s: c)
sb.append(s);
return sb.toString();
}
Nie mogę używać składni Java 5 tak bardzo, jak bym chciał (wierz lub nie, ostatnio używam 1.0.x), więc może jestem trochę zardzewiały, ale jestem pewien, że koncepcja jest poprawna .
dodawanie do edycji: Dołączanie ciągów może być powolne, ale jeśli pracujesz nad kodem GUI lub jakąś krótką procedurą, naprawdę nie ma znaczenia, czy zajmie ci to 0,005 sekundy czy .006, więc jeśli masz kolekcję o nazwie „joinMe” że chcesz dołączyć do istniejącego ciągu „target”, nie byłoby przerażające, gdybyśmy po prostu wstawili to:
for(String s : joinMe)
target += s;
Jest to dość nieefektywne (i zły nawyk), ale nic nie będziesz w stanie dostrzec, chyba że istnieją tysiące ciągów lub jest to wewnątrz ogromnej pętli lub twój kod jest naprawdę krytyczny dla wydajności.
Co ważniejsze, jest łatwy do zapamiętania, krótki, szybki i bardzo czytelny. Wydajność nie zawsze jest automatycznym zwycięzcą w wyborach projektowych.
Oto dość prosta odpowiedź. Używaj, +=ponieważ jest mniej kodu i pozwól optymalizatorowi przekonwertować go na plik StringBuilder. Używając tej metody, nie musisz wykonywać żadnych sprawdzeń „jest ostatnia” w pętli (poprawa wydajności) i nie musisz się martwić usuwaniem na końcu żadnych ograniczników.
Iterator<String> iter = args.iterator();
output += iter.hasNext() ? iter.next() : "";
while (iter.hasNext()) {
output += "," + iter.next();
}
Nie chciałem importować całej biblioteki Apache, aby dodać prostą funkcję łączenia, więc oto mój hack.
public String join(String delim, List<String> destinations) {
StringBuilder sb = new StringBuilder();
int delimLength = delim.length();
for (String s: destinations) {
sb.append(s);
sb.append(delim);
}
// we have appended the delimiter to the end
// in the previous for-loop. Let's now remove it.
if (sb.length() >= delimLength) {
return sb.substring(0, sb.length() - delimLength);
} else {
return sb.toString();
}
}
removeCharAtnie istnieje, a cała funkcja nie zwraca już ciągu znaków ... Naprawi to.
Jeśli chcesz połączyć (połączyć) kilka ciągów w jeden, powinieneś użyć StringBuilder. Jest to o wiele lepsze niż używanie
for(String s : joinMe)
target += s;
Występuje również niewielka przewaga wydajności nad StringBuffer, ponieważ StringBuilder nie używa synchronizacji.
W przypadku metody użyteczności ogólnego przeznaczenia, takiej jak ta, będzie ona (ostatecznie) wywoływana wiele razy w wielu sytuacjach, więc należy ją wydajnie i nie przydzielać wielu obiektów przejściowych. Zaprofilowaliśmy wiele, wiele różnych aplikacji Java i prawie zawsze stwierdzamy, że konkatenacja ciągów i alokacje ciągów / znaków [] zajmują znaczną ilość czasu / pamięci.
Nasza kolekcja wielokrotnego użytku -> metoda string najpierw oblicza rozmiar wymaganego wyniku, a następnie tworzy StringBuilder o tym początkowym rozmiarze; pozwala to uniknąć niepotrzebnego podwajania / kopiowania wewnętrznego znaku char [] używanego podczas dołączania ciągów.
Napisałem własne:
public static String join(Collection<String> col, String delim) {
StringBuilder sb = new StringBuilder();
Iterator<String> iter = col.iterator();
if (iter.hasNext())
sb.append(iter.next().toString());
while (iter.hasNext()) {
sb.append(delim);
sb.append(iter.next().toString());
}
return sb.toString();
}
ale Collectionnie jest obsługiwany przez JSP, więc dla funkcji tagów napisałem:
public static String join(List<?> list, String delim) {
int len = list.size();
if (len == 0)
return "";
StringBuilder sb = new StringBuilder(list.get(0).toString());
for (int i = 1; i < len; i++) {
sb.append(delim);
sb.append(list.get(i).toString());
}
return sb.toString();
}
i wstaw do .tldakt:
<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee"
<function>
<name>join</name>
<function-class>com.core.util.ReportUtil</function-class>
<function-signature>java.lang.String join(java.util.List, java.lang.String)</function-signature>
</function>
</taglib>
i używaj go w plikach JSP jako:
<%@taglib prefix="funnyFmt" uri="tag:com.core.util,2013:funnyFmt"%>
${funnyFmt:join(books, ", ")}
StringUtils to całkiem przydatna klasa w bibliotece Apache Commons Lang.
Jest coś, MessageFormat.format()co działa jak C # String.Format().
Widzę wiele nadmiernie złożonych implementacji String.Join tutaj. Jeśli nie masz Javy 1.8 i nie chcesz importować nowej biblioteki, poniższa implementacja powinna wystarczyć.
public String join(Collection<String> col, String delim) {
StringBuilder sb = new StringBuilder();
for ( String s : col ) {
if ( sb.length() != 0 ) sb.append(delim);
sb.append(s);
}
return sb.toString();
}
ArrayList<Double> j=new ArrayList<>;
j.add(1);
j.add(.92);
j.add(3);
String ntop=j.toString(); //ntop= "[1, 0.92, 3]"
Zasadniczo String ntop przechowuje wartość całej kolekcji z separatorami przecinkowymi i nawiasami.
Po prostu użyłbym operatora konkatenacji ciągów „+”, aby połączyć dwa ciągi. s1 += s2;