I have a set of files in a folder, and all of them starting with a similar name, except one. Here is an example:
Coordinate.txt
Spectrum_1.txt
Spectrum_2.txt
Just another way to do it, but using the power of java8
List<Path> x = Files.list(Paths.get("C:\\myPath\\Tools"))
.filter(p -> Files.exists(p))
.map(s -> s.getFileName())
.sorted()
.collect(Collectors.toList());
x.forEach(System.out::println);
You can find solution to your problem in comment above, but taking into consideration that only link had been published I'm giving code from that site. Worked great.
You need to create your own AlphanumericalComparator.
import java.io.File;
import java.util.Comparator;
public class AlphanumFileComparator implements Comparator
{
private final boolean isDigit(char ch)
{
return ch >= 48 && ch <= 57;
}
private final String getChunk(String s, int slength, int marker)
{
StringBuilder chunk = new StringBuilder();
char c = s.charAt(marker);
chunk.append(c);
marker++;
if (isDigit(c))
{
while (marker < slength)
{
c = s.charAt(marker);
if (!isDigit(c))
break;
chunk.append(c);
marker++;
}
} else
{
while (marker < slength)
{
c = s.charAt(marker);
if (isDigit(c))
break;
chunk.append(c);
marker++;
}
}
return chunk.toString();
}
public int compare(Object o1, Object o2)
{
if (!(o1 instanceof File) || !(o2 instanceof File))
{
return 0;
}
File f1 = (File)o1;
File f2 = (File)o2;
String s1 = f1.getName();
String s2 = f2.getName();
int thisMarker = 0;
int thatMarker = 0;
int s1Length = s1.length();
int s2Length = s2.length();
while (thisMarker < s1Length && thatMarker < s2Length)
{
String thisChunk = getChunk(s1, s1Length, thisMarker);
thisMarker += thisChunk.length();
String thatChunk = getChunk(s2, s2Length, thatMarker);
thatMarker += thatChunk.length();
/** If both chunks contain numeric characters, sort them numerically **/
int result = 0;
if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0)))
{
// Simple chunk comparison by length.
int thisChunkLength = thisChunk.length();
result = thisChunkLength - thatChunk.length();
// If equal, the first different number counts
if (result == 0)
{
for (int i = 0; i < thisChunkLength; i++)
{
result = thisChunk.charAt(i) - thatChunk.charAt(i);
if (result != 0)
{
return result;
}
}
}
} else
{
result = thisChunk.compareTo(thatChunk);
}
if (result != 0)
return result;
}
return s1Length - s2Length;
}
}
2. Sort your files, depending on this class.
File[] listOfFiles = rootFolder.listFiles();
Arrays.sort(listOfFiles, new AlphanumFileComparator() );
...to sth with your files.
Hope it helps. It worked for me, like a charm.
Solution from: http://www.davekoelle.com/files/AlphanumComparator.java here
The currently accepted answer does this only for numeric suffixes of files that are always called the same name (i.e. ignoring the prefix).
A much more generic solution, which I blogged about here, works with any file name, splitting names in segments and ordering the segments numerically (if both segments are numbers) or lexicographically, otherwise. Idea inspired from this answer:
public final class FilenameComparator implements Comparator<String> {
private static final Pattern NUMBERS =
Pattern.compile("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)");
@Override public final int compare(String o1, String o2) {
// Optional "NULLS LAST" semantics:
if (o1 == null || o2 == null)
return o1 == null ? o2 == null ? 0 : -1 : 1;
// Splitting both input strings by the above patterns
String[] split1 = NUMBERS.split(o1);
String[] split2 = NUMBERS.split(o2);
for (int i = 0; i < Math.min(split1.length, split2.length); i++) {
char c1 = split1[i].charAt(0);
char c2 = split2[i].charAt(0);
int cmp = 0;
// If both segments start with a digit, sort them numerically using
// BigInteger to stay safe
if (c1 >= '0' && c1 <= '9' && c2 >= '0' && c2 <= '9')
cmp = new BigInteger(split1[i]).compareTo(new BigInteger(split2[i]));
// If we haven't sorted numerically before, or if numeric sorting yielded
// equality (e.g 007 and 7) then sort lexicographically
if (cmp == 0)
cmp = split1[i].compareTo(split2[i]);
// Abort once some prefix has unequal ordering
if (cmp != 0)
return cmp;
}
// If we reach this, then both strings have equally ordered prefixes, but
// maybe one string is longer than the other (i.e. has more segments)
return split1.length - split2.length;
}
}
This can also handle version with subversions, e.g. things like version-1.2.3.txt