It seems that the problem is a little messy. This seems to be the situation:
You have a List
of user inputs. You have have a database field that is, itself, as comma separated list.
You need to see if there is a permutation in the database that matches one of the permutations of your input.
First your query. From this answer this is how to create a prepared statement with an IN
clause.
PreparedStatement st1 = con.prepareStatement("SELECT * FROM SHOP WHERE DRINKS IN (?)");
Array array = con.createArrayOf("VARCHAR", stringPermutations);
st1.setArray(1, array);
This essentially queries your database where DRINKS
is one of IN
.
Now onto creating the stringPermutations
. This needs to be an Object[]
of the comma separated permutations - to match the database.
First, get a Set<String>
of the user inputs: something like this ought to do:
public Set<String> getInputs(final JTextComponent component) {
final Set<String> inputs = new LinkedHashSet<>();
for (final String input : component.getText().split("\\s+")) {
inputs.add(input);
}
return inputs;
}
In Java 8:
public Set<String> getInputs(final JTextComponent component) {
return Stream.of(component.getText().split("\\s+")).
collect(Collectors.toSet());
}
Now you need to permute the inputs to get all possible combinations. You will have n!
of them - this is many:
public List<Set<String>> permutations(final Set<String> input) {
if (input.size() == 1) {
return Arrays.asList(input);
}
final List<Set<String>> output = new ArrayList<>();
final Iterator<String> iter = input.iterator();
while (iter.hasNext()) {
final String item = iter.next();
final Set<String> copy = new LinkedHashSet<>(input);
copy.remove(item);
for (final Set<String> rest : permutations(copy)) {
rest.add(item);
output.add(rest);
}
}
return output;
}
This is a recursive algorithm, it's pretty standard. The output is something like this:
[D, C, B, A]
[C, D, B, A]
[D, B, C, A]
[B, D, C, A]
[C, B, D, A]
[B, C, D, A]
[D, C, A, B]
[C, D, A, B]
[D, A, C, B]
[A, D, C, B]
[C, A, D, B]
[A, C, D, B]
[D, B, A, C]
[B, D, A, C]
[D, A, B, C]
[A, D, B, C]
[B, A, D, C]
[A, B, D, C]
[C, B, A, D]
[B, C, A, D]
[C, A, B, D]
[A, C, B, D]
[B, A, C, D]
[A, B, C, D]
So, for 4
input you get 4! = 24
permutations. Now we need to join those individual items into comma separated lists:
public List<String> combine(final List<Set<String>> toJoin) {
final List<String> outputs = new ArrayList<>(toJoin.size());
for (final Set<String> items : toJoin) {
outputs.add(join(items));
}
return outputs;
}
private String join(final Set<String> items) {
final Iterator<String> iter = items.iterator();
final StringBuilder sb = new StringBuilder();
sb.append(iter.next());
while (iter.hasNext()) {
sb.append(", ").append(iter.next());
}
return sb.toString();
}
Again, tidier in Java 8:
public List<String> combine(final List<Set<String>> toJoin) {
return toJoin.stream().
map(items -> items.stream().collect(Collectors.joining(", "))).
collect(Collectors.toList());
}
Finally we can get the Object[]
input to the PeparedStatement
:
final Object[] stringPermutations = combine(permutations(getInputs(field))).toArray();
PreparedStatement st1 = con.prepareStatement("SELECT * FROM SHOP WHERE DRINKS IN (?)");
Array array = con.createArrayOf("VARCHAR", stringPermutations);
st1.setArray(1, array);
It should further be noted that you should be closing your resources, you can use the try-with-resources
construct:
final Object[] stringPermutations = combine(permutations(getInputs(field))).toArray();
try (final Connection con = getConnection()) {
try (final PreparedStatement st1 = con.prepareStatement("SELECT * FROM SHOP WHERE DRINKS IN (?)")) {
Array array = con.createArrayOf("VARCHAR", stringPermutations);
st1.setArray(1, array);
try (final ResultSet rs = st1.executeQuery()) {
//do stufd
}
}
}